/*
 * Copyright (C) 2017 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <array>
#include <cstdint>
#include <memory>

#include <gtest/gtest.h>

#include "netdutils/Handle.h"
#include "netdutils/Math.h"
#include "netdutils/MockSyscalls.h"
#include "netdutils/Netfilter.h"
#include "netdutils/Netlink.h"
#include "netdutils/Slice.h"
#include "netdutils/Status.h"
#include "netdutils/StatusOr.h"
#include "netdutils/Syscalls.h"

using testing::ByMove;
using testing::DoAll;
using testing::Invoke;
using testing::Mock;
using testing::Return;
using testing::StrictMock;
using testing::_;

namespace android {
namespace netdutils {

class SyscallsTest : public testing::Test {
  protected:
    StrictMock<ScopedMockSyscalls> mSyscalls;
};

TEST(syscalls, scopedMock) {
    auto& old = sSyscalls.get();
    {
        StrictMock<ScopedMockSyscalls> s;
        EXPECT_EQ(&s, &sSyscalls.get());
    }
    EXPECT_EQ(&old, &sSyscalls.get());
}

TEST_F(SyscallsTest, open) {
    const char kPath[] = "/test/path/please/ignore";
    constexpr Fd kFd(40);
    constexpr int kFlags = 883;
    constexpr mode_t kMode = 37373;
    const auto& sys = sSyscalls.get();
    EXPECT_CALL(mSyscalls, open(kPath, kFlags, kMode)).WillOnce(Return(ByMove(UniqueFd(kFd))));
    auto result = sys.open(kPath, kFlags, kMode);
    EXPECT_EQ(status::ok, result.status());
    EXPECT_EQ(kFd, result.value());
}

TEST_F(SyscallsTest, getsockname) {
    constexpr Fd kFd(40);
    sockaddr_nl expected = {};
    auto& sys = sSyscalls.get();

    // Success
    EXPECT_CALL(mSyscalls, getsockname(kFd, _, _))
        .WillOnce(Invoke([expected](Fd, sockaddr* addr, socklen_t* addrlen) {
            memcpy(addr, &expected, sizeof(expected));
            EXPECT_EQ(*addrlen, static_cast<socklen_t>(sizeof(expected)));
            return status::ok;
        }));
    const auto result = sys.getsockname<sockaddr_nl>(kFd);
    EXPECT_TRUE(isOk(result));
    EXPECT_EQ(expected, result.value());

    // Failure
    const Status kError = statusFromErrno(EINVAL, "test");
    EXPECT_CALL(mSyscalls, getsockname(kFd, _, _)).WillOnce(Return(kError));
    EXPECT_EQ(kError, sys.getsockname<sockaddr_nl>(kFd).status());
}

TEST_F(SyscallsTest, setsockopt) {
    constexpr Fd kFd(40);
    constexpr int kLevel = 50;
    constexpr int kOptname = 70;
    sockaddr_nl expected = {};
    auto& sys = sSyscalls.get();

    // Success
    EXPECT_CALL(mSyscalls, setsockopt(kFd, kLevel, kOptname, &expected, sizeof(expected)))
        .WillOnce(Return(status::ok));
    EXPECT_EQ(status::ok, sys.setsockopt(kFd, kLevel, kOptname, expected));

    // Failure
    const Status kError = statusFromErrno(EINVAL, "test");
    EXPECT_CALL(mSyscalls, setsockopt(kFd, kLevel, kOptname, &expected, sizeof(expected)))
        .WillOnce(Return(kError));
    EXPECT_EQ(kError, sys.setsockopt(kFd, kLevel, kOptname, expected));
}

TEST_F(SyscallsTest, getsockopt) {
    constexpr Fd kFd(40);
    constexpr int kLevel = 50;
    constexpr int kOptname = 70;
    sockaddr_nl expected = {};
    socklen_t optLen = 0;
    auto& sys = sSyscalls.get();

    // Success
    EXPECT_CALL(mSyscalls, getsockopt(kFd, kLevel, kOptname, &expected, &optLen))
        .WillOnce(Return(status::ok));
    EXPECT_EQ(status::ok, sys.getsockopt(kFd, kLevel, kOptname, &expected, &optLen));

    // Failure
    const Status kError = statusFromErrno(EINVAL, "test");
    EXPECT_CALL(mSyscalls, getsockopt(kFd, kLevel, kOptname, &expected, &optLen))
        .WillOnce(Return(kError));
    EXPECT_EQ(kError, sys.getsockopt(kFd, kLevel, kOptname, &expected, &optLen));
}

TEST_F(SyscallsTest, bind) {
    constexpr Fd kFd(40);
    sockaddr_nl expected = {};
    auto& sys = sSyscalls.get();

    // Success
    EXPECT_CALL(mSyscalls, bind(kFd, asSockaddrPtr(&expected), sizeof(expected)))
        .WillOnce(Return(status::ok));
    EXPECT_EQ(status::ok, sys.bind(kFd, expected));

    // Failure
    const Status kError = statusFromErrno(EINVAL, "test");
    EXPECT_CALL(mSyscalls, bind(kFd, asSockaddrPtr(&expected), sizeof(expected)))
        .WillOnce(Return(kError));
    EXPECT_EQ(kError, sys.bind(kFd, expected));
}

TEST_F(SyscallsTest, connect) {
    constexpr Fd kFd(40);
    sockaddr_nl expected = {};
    auto& sys = sSyscalls.get();

    // Success
    EXPECT_CALL(mSyscalls, connect(kFd, asSockaddrPtr(&expected), sizeof(expected)))
        .WillOnce(Return(status::ok));
    EXPECT_EQ(status::ok, sys.connect(kFd, expected));

    // Failure
    const Status kError = statusFromErrno(EINVAL, "test");
    EXPECT_CALL(mSyscalls, connect(kFd, asSockaddrPtr(&expected), sizeof(expected)))
        .WillOnce(Return(kError));
    EXPECT_EQ(kError, sys.connect(kFd, expected));
}

TEST_F(SyscallsTest, sendto) {
    constexpr Fd kFd(40);
    constexpr int kFlags = 0;
    std::array<char, 10> payload;
    const auto slice = makeSlice(payload);
    sockaddr_nl expected = {};
    auto& sys = sSyscalls.get();

    // Success
    EXPECT_CALL(mSyscalls, sendto(kFd, slice, kFlags, asSockaddrPtr(&expected), sizeof(expected)))
        .WillOnce(Return(slice.size()));
    EXPECT_EQ(status::ok, sys.sendto(kFd, slice, kFlags, expected));
}

TEST_F(SyscallsTest, recvfrom) {
    constexpr Fd kFd(40);
    constexpr int kFlags = 0;
    std::array<char, 10> payload;
    const auto dst = makeSlice(payload);
    const auto used = take(dst, 8);
    sockaddr_nl expected = {};
    auto& sys = sSyscalls.get();

    // Success
    EXPECT_CALL(mSyscalls, recvfrom(kFd, dst, kFlags, _, _))
        .WillOnce(Invoke([expected, used](Fd, const Slice, int, sockaddr* src, socklen_t* srclen) {
            memcpy(src, &expected, sizeof(src));
            *srclen = sizeof(expected);
            return used;
        }));
    auto result = sys.recvfrom<sockaddr_nl>(kFd, dst, kFlags);
    EXPECT_EQ(status::ok, result.status());
    EXPECT_EQ(used, result.value().first);
    EXPECT_EQ(expected, result.value().second);
}

}  // namespace netdutils
}  // namespace android
