package com.red.circle.other.infra.utils;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;

import com.alibaba.fastjson.JSON;
import org.junit.jupiter.api.Test;

public class IpCountryUtilsTest {

  @Test
  public void normalizeIpSbMainlandChina() {
    IpCountryUtils.IpGeoData data = IpCountryUtils.normalizeIpData(
        "ip.sb",
        JSON.parseObject("""
            {"country":"China","country_code":"CN","timezone":"Asia/Shanghai"}
            """)
    );

    assertEquals("CN", data.countryCode());
    assertEquals("China", data.countryName());
    assertTrue(IpCountryUtils.isMainlandChina(data));
  }

  @Test
  public void normalizeFreeIpApiMainlandChina() {
    IpCountryUtils.IpGeoData data = IpCountryUtils.normalizeIpData(
        "freeipapi",
        JSON.parseObject("""
            {"countryName":"China","countryCode":"CN","regionName":"Shandong"}
            """)
    );

    assertEquals("CN", data.countryCode());
    assertEquals("Shandong", data.region());
    assertTrue(IpCountryUtils.isMainlandChina(data));
  }

  @Test
  public void normalizeIpWhoisUnitedStates() {
    IpCountryUtils.IpGeoData data = IpCountryUtils.normalizeIpData(
        "ipwhois",
        JSON.parseObject("""
            {"success":true,"country":"United States","country_code":"US","region":"California"}
            """)
    );

    assertEquals("US", data.countryCode());
    assertFalse(IpCountryUtils.isMainlandChina(data));
  }

  @Test
  public void normalizeIpNcGyMainlandChina() {
    IpCountryUtils.IpGeoData data = IpCountryUtils.normalizeIpData(
        "ip.nc.gy",
        JSON.parseObject("""
            {
              "country":{"iso_code":"CN","names":{"en":"China","zh-CN":"中国"}},
              "subdivisions":[{"names":{"en":"Jiangsu","zh-CN":"江苏"}}]
            }
            """)
    );

    assertEquals("CN", data.countryCode());
    assertEquals("中国", data.countryName());
    assertEquals("江苏", data.region());
    assertTrue(IpCountryUtils.isMainlandChina(data));
  }

  @Test
  public void allowHongKongRegion() {
    IpCountryUtils.IpGeoData data = new IpCountryUtils.IpGeoData("CN", "中国", "香港", "test");

    assertFalse(IpCountryUtils.isMainlandChina(data));
    assertFalse(IpCountryUtils.isBlockedIpRegion(data));
  }

  @Test
  public void allowHongKongCountryCode() {
    IpCountryUtils.IpGeoData data = new IpCountryUtils.IpGeoData("HK", "Hong Kong", "", "test");

    assertFalse(IpCountryUtils.isMainlandChina(data));
    assertFalse(IpCountryUtils.isBlockedIpRegion(data));
  }

  @Test
  public void blockMacauCountryCode() {
    IpCountryUtils.IpGeoData data = new IpCountryUtils.IpGeoData("MO", "Macao", "", "test");

    assertTrue(IpCountryUtils.isBlockedIpRegion(data));
  }

  @Test
  public void allowSingaporeCountryCode() {
    IpCountryUtils.IpGeoData data = new IpCountryUtils.IpGeoData("SG", "Singapore", "", "test");

    assertFalse(IpCountryUtils.isBlockedIpRegion(data));
  }

  @Test
  public void allowTaiwanRegion() {
    IpCountryUtils.IpGeoData data = new IpCountryUtils.IpGeoData("CN", "中国", "台湾", "test");

    assertFalse(IpCountryUtils.isMainlandChina(data));
    assertFalse(IpCountryUtils.isBlockedIpRegion(data));
  }

  @Test
  public void allowTaiwanCountryCode() {
    IpCountryUtils.IpGeoData data = new IpCountryUtils.IpGeoData("TW", "Taiwan", "", "test");

    assertFalse(IpCountryUtils.isBlockedIpRegion(data));
  }
}
