/*
 * 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, 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
