// Copyright 2018 The ChromiumOS Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "patchpanel/subnet.h"

#include <arpa/inet.h>
#include <stdint.h>

#include <string>
#include <utility>
#include <vector>

#include <base/functional/bind.h>
#include <base/functional/callback_helpers.h>
#include <base/strings/string_util.h>
#include <gtest/gtest.h>

#include "patchpanel/net_util.h"

// TODO(akahuang): Change the unittest to concrete test cases, instead of using
// lots of calculation and for loop inside the test. (go/tott/643)

namespace patchpanel {
namespace {

constexpr net_base::IPv4Address kContainerBaseAddress(100, 115, 92, 192);
constexpr net_base::IPv4Address kVmBaseAddress(100, 115, 92, 24);
constexpr net_base::IPv4Address kParallelsBaseAddress(100, 115, 92, 128);

constexpr uint32_t kContainerSubnetPrefixLength = 28;
constexpr uint32_t kVmSubnetPrefixLength = 30;
constexpr uint32_t kParallelsSubnetPrefixLength = 28;

// kExpectedAvailableCount[i] == AvailableCount() for subnet with prefix_length
// i.
constexpr uint32_t kExpectedAvailableCount[] = {
    0xfffffffe, 0x7ffffffe, 0x3ffffffe, 0x1ffffffe, 0xffffffe, 0x7fffffe,
    0x3fffffe,  0x1fffffe,  0xfffffe,   0x7ffffe,   0x3ffffe,  0x1ffffe,
    0xffffe,    0x7fffe,    0x3fffe,    0x1fffe,    0xfffe,    0x7ffe,
    0x3ffe,     0x1ffe,     0xffe,      0x7fe,      0x3fe,     0x1fe,
    0xfe,       0x7e,       0x3e,       0x1e,       0xe,       0x6,
    0x2,        0x0,
};

class VmSubnetTest : public ::testing::TestWithParam<uint32_t> {};
class ContainerSubnetTest : public ::testing::TestWithParam<uint32_t> {};
class PrefixTest : public ::testing::TestWithParam<int> {};

void SetTrue(bool* value) {
  *value = true;
}

}  // namespace

TEST_P(VmSubnetTest, CIDRAtOffset) {
  uint32_t index = GetParam();
  Subnet subnet(
      *net_base::IPv4CIDR::CreateFromAddressAndPrefix(
          AddOffset(kVmBaseAddress, index * 4), kVmSubnetPrefixLength),
      base::DoNothing());

  for (uint32_t offset = 1; offset <= subnet.AvailableCount(); ++offset) {
    const auto expected_cidr = *net_base::IPv4CIDR::CreateFromAddressAndPrefix(
        AddOffset(kVmBaseAddress, index * 4 + offset), kVmSubnetPrefixLength);
    EXPECT_EQ(expected_cidr, subnet.CIDRAtOffset(offset));
  }
}

INSTANTIATE_TEST_SUITE_P(AllValues,
                         VmSubnetTest,
                         ::testing::Range(uint32_t{0}, uint32_t{26}));

TEST_P(ContainerSubnetTest, CIDRAtOffset) {
  uint32_t index = GetParam();
  Subnet subnet(*net_base::IPv4CIDR::CreateFromAddressAndPrefix(
                    AddOffset(kContainerBaseAddress, index * 16),
                    kContainerSubnetPrefixLength),
                base::DoNothing());

  for (uint32_t offset = 1; offset <= subnet.AvailableCount(); ++offset) {
    const auto expected_cidr = *net_base::IPv4CIDR::CreateFromAddressAndPrefix(
        AddOffset(kContainerBaseAddress, index * 16 + offset),
        kContainerSubnetPrefixLength);
    EXPECT_EQ(expected_cidr, subnet.CIDRAtOffset(offset));
  }
}

INSTANTIATE_TEST_SUITE_P(AllValues,
                         ContainerSubnetTest,
                         ::testing::Range(uint32_t{1}, uint32_t{4}));

TEST_P(PrefixTest, AvailableCount) {
  int prefix_length = GetParam();

  Subnet subnet(
      *net_base::IPv4CIDR::CreateFromAddressAndPrefix({}, prefix_length),
      base::DoNothing());
  EXPECT_EQ(kExpectedAvailableCount[prefix_length], subnet.AvailableCount());
}

INSTANTIATE_TEST_SUITE_P(AllValues, PrefixTest, ::testing::Range(8, 32));

TEST(SubtnetAddress, StringConversion) {
  Subnet container_subnet(
      *net_base::IPv4CIDR::CreateFromAddressAndPrefix(
          kContainerBaseAddress, kContainerSubnetPrefixLength),
      base::DoNothing());
  EXPECT_EQ("100.115.92.192/28", container_subnet.base_cidr().ToString());
  {
    EXPECT_EQ(*net_base::IPv4CIDR::CreateFromCIDRString("100.115.92.193/28"),
              container_subnet.CIDRAtOffset(1));
    EXPECT_EQ(*net_base::IPv4CIDR::CreateFromCIDRString("100.115.92.194/28"),
              container_subnet.CIDRAtOffset(2));
    EXPECT_EQ(*net_base::IPv4CIDR::CreateFromCIDRString("100.115.92.205/28"),
              container_subnet.CIDRAtOffset(13));
    EXPECT_EQ(*net_base::IPv4CIDR::CreateFromCIDRString("100.115.92.206/28"),
              container_subnet.CIDRAtOffset(14));
  }

  Subnet vm_subnet(*net_base::IPv4CIDR::CreateFromAddressAndPrefix(
                       kVmBaseAddress, kVmSubnetPrefixLength),
                   base::DoNothing());
  EXPECT_EQ("100.115.92.24/30", vm_subnet.base_cidr().ToString());
  {
    EXPECT_EQ(*net_base::IPv4CIDR::CreateFromCIDRString("100.115.92.25/30"),
              vm_subnet.CIDRAtOffset(1));
    EXPECT_EQ(*net_base::IPv4CIDR::CreateFromCIDRString("100.115.92.26/30"),
              vm_subnet.CIDRAtOffset(2));
  }

  Subnet parallels_subnet(
      *net_base::IPv4CIDR::CreateFromAddressAndPrefix(
          kParallelsBaseAddress, kParallelsSubnetPrefixLength),
      base::DoNothing());
  EXPECT_EQ("100.115.92.128/28", parallels_subnet.base_cidr().ToString());
  {
    EXPECT_EQ(*net_base::IPv4CIDR::CreateFromCIDRString("100.115.92.129/28"),
              parallels_subnet.CIDRAtOffset(1));
    EXPECT_EQ(*net_base::IPv4CIDR::CreateFromCIDRString("100.115.92.130/28"),
              parallels_subnet.CIDRAtOffset(2));
    EXPECT_EQ(*net_base::IPv4CIDR::CreateFromCIDRString("100.115.92.141/28"),
              parallels_subnet.CIDRAtOffset(13));
    EXPECT_EQ(*net_base::IPv4CIDR::CreateFromCIDRString("100.115.92.142/28"),
              parallels_subnet.CIDRAtOffset(14));
  }
}

// Tests that the Subnet runs the provided cleanup callback when it gets
// destroyed.
TEST(Subnet, Cleanup) {
  bool called = false;

  {
    Subnet subnet(*net_base::IPv4CIDR::CreateFromAddressAndPrefix({}, 24),
                  base::BindOnce(&SetTrue, &called));
  }

  EXPECT_TRUE(called);
}

}  // namespace patchpanel
