# frozen_string_literal: true

require "test_helper"

class Ipv6RangeTest < ActiveSupport::TestCase
  test "creates range from CIDR notation" do
    range = Ipv6Range.create!(cidr: "2001:db8::/32")

    assert_equal 32, range.network_prefix
    assert range.network_start.present?
    assert range.network_end.present?
  end

  test "calculates correct range for /128 single IP" do
    range = Ipv6Range.create!(cidr: "2001:db8::1/128")

    assert_equal 128, range.network_prefix
    assert_equal range.network_start, range.network_end
  end

  test "validates network_prefix range" do
    range = Ipv6Range.new(cidr: "2001:db8::/32")
    range.network_prefix = 129

    assert_not range.valid?
    assert_includes range.errors[:network_prefix], "must be less than or equal to 128"
  end

  test "contains_ip? returns true for IP in range" do
    range = Ipv6Range.create!(cidr: "2001:db8::/32")

    assert range.contains_ip?("2001:db8::1")
    assert range.contains_ip?("2001:db8:ffff:ffff:ffff:ffff:ffff:ffff")
  end

  test "contains_ip? returns false for IP outside range" do
    range = Ipv6Range.create!(cidr: "2001:db8::/32")

    assert_not range.contains_ip?("2001:db9::1")
    assert_not range.contains_ip?("fe80::1")
  end

  test "contains_ip class method finds matching ranges" do
    range1 = Ipv6Range.create!(cidr: "2001:db8::/32")
    range2 = Ipv6Range.create!(cidr: "fe80::/10")

    results = Ipv6Range.contains_ip("2001:db8::1")

    assert_includes results, range1
    assert_not_includes results, range2
  end

  test "contains_ip returns most specific range first" do
    broad_range = Ipv6Range.create!(cidr: "2001:db8::/32")
    specific_range = Ipv6Range.create!(cidr: "2001:db8:1::/48")

    results = Ipv6Range.contains_ip("2001:db8:1::5")

    assert_equal specific_range, results.first
  end

  test "to_cidr returns CIDR notation" do
    range = Ipv6Range.create!(cidr: "2001:db8::/32")

    # IPv6 addresses can be formatted differently
    assert range.to_cidr.include?("2001:db8")
    assert range.to_cidr.include?("/32")
  end

  test "datacenter scope returns datacenter IPs" do
    datacenter = Ipv6Range.create!(cidr: "2001:db8::/32", is_datacenter: true)
    regular = Ipv6Range.create!(cidr: "fe80::/10", is_datacenter: false)

    results = Ipv6Range.datacenter

    assert_includes results, datacenter
    assert_not_includes results, regular
  end

  test "stores and retrieves JSON metadata" do
    range = Ipv6Range.create!(cidr: "2001:db8::/32")
    range.additional_data_hash = { "notes" => "Test network", "verified" => true }
    range.save!

    range.reload
    data = range.additional_data_hash

    assert_equal "Test network", data["notes"]
    assert_equal true, data["verified"]
  end

  test "stores IP intelligence metadata" do
    range = Ipv6Range.create!(
      cidr: "2001:db8::/32",
      company: "IPv6 Corp",
      asn: 65000,
      asn_org: "AS IPv6",
      is_proxy: true,
      ip_api_country: "GB"
    )

    assert_equal "IPv6 Corp", range.company
    assert_equal 65000, range.asn
    assert range.is_proxy?
    assert_equal "GB", range.ip_api_country
  end
end
