import { Network, PeerStatus } from "@bindings/services/models.js";

// Flip to true to override the live daemon data in the Peers / Resources /
// Exit Nodes tabs with the hand-crafted fixtures below. The fixtures are
// designed to surface overflow / truncation bugs (very long FQDNs, ICE
// endpoints, domain lists, network ids) and exercise the three connection
// states + relayed / P2P / Rosenpass variants.
export const MOCK_ENABLED = false;

// Replace `real` with `mock` when MOCK_ENABLED. Pulled out so call sites read
// as "use the live X, or the mock if enabled" without per-site if/else noise.
export const mockOr = <T>(real: T, mock: T): T => (MOCK_ENABLED ? mock : real);

const SECONDS = (s: number) => Math.floor(Date.now() / 1000) - s;
const MINUTES = (m: number) => SECONDS(m * 60);
const HOURS = (h: number) => MINUTES(h * 60);
const DAYS = (d: number) => HOURS(d * 24);

export const mockPeers: PeerStatus[] = [
    // Kitchen-sink peer — every optional field populated at the same time so
    // the detail panel renders every Row (latency + bytes + handshake + ICE
    // local/remote + relay + networks + rosenpass + pubkey). Useful for
    // eyeballing layout at maximum density.
    new PeerStatus({
        ip: "100.64.0.1",
        ipv6: "fd00:dead:beef::1",
        pubKey: "MockKeyEverythingMaxedOutForLayoutTestingAA=",
        connStatus: "Connected",
        connStatusUpdateUnix: SECONDS(4),
        relayed: true,
        localIceCandidateType: "prflx",
        remoteIceCandidateType: "relay",
        localIceCandidateEndpoint: "[2001:db8:abcd:0012:0000:0000:0000:0001]:51820",
        remoteIceCandidateEndpoint: "relay-eu-central-1.netbird.io:443",
        fqdn: "everything-maxed-out-kitchen-sink-peer-with-long-name.subdomain.dev.example-company.netbird.cloud",
        bytesRx: 87_654_321_098,
        bytesTx: 43_210_987_654,
        latencyMs: 213,
        relayAddress:
            "rels://relay-eu-central-1.netbird.io:443/very/long/relay/path/segment/with/many/parts",
        lastHandshakeUnix: SECONDS(3),
        rosenpassEnabled: true,
        networks: [
            "10.0.0.0/8",
            "172.16.0.0/12",
            "192.168.0.0/16",
            "100.100.0.0/16",
            "10.50.50.0/24",
            "2001:db8::/32",
            "203.0.113.0/24",
            "198.51.100.0/24",
        ],
    }),
    new PeerStatus({
        ip: "100.64.0.2",
        pubKey: "MockKeyAlpha000000000000000000000000000000=",
        connStatus: "Connected",
        connStatusUpdateUnix: MINUTES(7),
        relayed: false,
        localIceCandidateType: "host",
        remoteIceCandidateType: "srflx",
        localIceCandidateEndpoint: "192.168.1.10:51820",
        remoteIceCandidateEndpoint: "203.0.113.42:51820",
        fqdn: "alpha.netbird.cloud",
        bytesRx: 12_345_678,
        bytesTx: 9_876_543,
        latencyMs: 18,
        relayAddress: "",
        lastHandshakeUnix: SECONDS(12),
        rosenpassEnabled: false,
        networks: ["10.0.0.0/24"],
    }),
    new PeerStatus({
        ip: "100.64.0.3",
        pubKey: "MockKeyLongFqdn000000000000000000000000000=",
        connStatus: "Connected",
        connStatusUpdateUnix: HOURS(2),
        relayed: false,
        localIceCandidateType: "srflx",
        remoteIceCandidateType: "srflx",
        localIceCandidateEndpoint: "198.51.100.7:41234",
        remoteIceCandidateEndpoint: "203.0.113.99:51820",
        fqdn: "very-long-hostname-with-many-segments-to-test-overflow-handling.subdomain.example-company.netbird.cloud",
        bytesRx: 4_500_000_000,
        bytesTx: 1_200_000_000,
        latencyMs: 87,
        relayAddress: "",
        lastHandshakeUnix: SECONDS(45),
        rosenpassEnabled: false,
        networks: [],
    }),
    new PeerStatus({
        ip: "100.64.0.4",
        pubKey: "MockKeyConnecting00000000000000000000000000=",
        connStatus: "Connecting",
        connStatusUpdateUnix: SECONDS(3),
        relayed: false,
        localIceCandidateType: "",
        remoteIceCandidateType: "",
        localIceCandidateEndpoint: "",
        remoteIceCandidateEndpoint: "",
        fqdn: "edge-server.netbird.cloud",
        bytesRx: 0,
        bytesTx: 0,
        latencyMs: 0,
        relayAddress: "",
        lastHandshakeUnix: 0,
        rosenpassEnabled: false,
        networks: [],
    }),
    new PeerStatus({
        ip: "100.64.0.5",
        pubKey: "MockKeyOfflineOld0000000000000000000000000=",
        connStatus: "Idle",
        connStatusUpdateUnix: DAYS(4),
        relayed: false,
        localIceCandidateType: "",
        remoteIceCandidateType: "",
        localIceCandidateEndpoint: "",
        remoteIceCandidateEndpoint: "",
        fqdn: "old-peer-offline.netbird.cloud",
        bytesRx: 0,
        bytesTx: 0,
        latencyMs: 0,
        relayAddress: "",
        lastHandshakeUnix: DAYS(4),
        rosenpassEnabled: false,
        networks: [],
    }),
    new PeerStatus({
        ip: "100.64.0.6",
        pubKey: "MockKeyRelayed00000000000000000000000000000=",
        connStatus: "Connected",
        connStatusUpdateUnix: MINUTES(30),
        relayed: true,
        localIceCandidateType: "relay",
        remoteIceCandidateType: "relay",
        localIceCandidateEndpoint: "relay-eu-central-1.netbird.io:443",
        remoteIceCandidateEndpoint: "relay-eu-central-1.netbird.io:443",
        fqdn: "relayed-host-behind-strict-nat.corp.example.com",
        bytesRx: 250_000,
        bytesTx: 180_000,
        latencyMs: 142,
        relayAddress: "rels://relay-eu-central-1.netbird.io:443/very/long/relay/path/segment",
        lastHandshakeUnix: SECONDS(8),
        rosenpassEnabled: false,
        networks: ["10.10.0.0/16", "192.168.50.0/24"],
    }),
    new PeerStatus({
        ip: "100.64.0.7",
        pubKey: "MockKeyIPv6000000000000000000000000000000000=",
        connStatus: "Connected",
        connStatusUpdateUnix: HOURS(1),
        relayed: false,
        localIceCandidateType: "host",
        remoteIceCandidateType: "host",
        localIceCandidateEndpoint: "[2001:db8:85a3:0000:0000:8a2e:0370:7334]:51820",
        remoteIceCandidateEndpoint: "[fe80::1ff:fe23:4567:890a]:51820",
        fqdn: "ipv6-only-host.netbird.cloud",
        bytesRx: 999_999,
        bytesTx: 1_500_000,
        latencyMs: 64,
        relayAddress: "",
        lastHandshakeUnix: SECONDS(22),
        rosenpassEnabled: false,
        networks: [],
    }),
    new PeerStatus({
        ip: "100.64.0.8",
        pubKey: "MockKeyRosenpass0000000000000000000000000000=",
        connStatus: "Connected",
        connStatusUpdateUnix: MINUTES(15),
        relayed: false,
        localIceCandidateType: "prflx",
        remoteIceCandidateType: "prflx",
        localIceCandidateEndpoint: "10.0.0.50:51820",
        remoteIceCandidateEndpoint: "203.0.113.200:51820",
        fqdn: "rosenpass-secure.netbird.cloud",
        bytesRx: 50_000,
        bytesTx: 50_000,
        latencyMs: 24,
        relayAddress: "",
        lastHandshakeUnix: SECONDS(5),
        rosenpassEnabled: true,
        networks: [],
    }),
    new PeerStatus({
        ip: "100.64.0.9",
        pubKey: "MockKeyMultiNet00000000000000000000000000000=",
        connStatus: "Connected",
        connStatusUpdateUnix: HOURS(5),
        relayed: false,
        localIceCandidateType: "host",
        remoteIceCandidateType: "srflx",
        localIceCandidateEndpoint: "10.0.0.51:51820",
        remoteIceCandidateEndpoint: "203.0.113.201:51820",
        fqdn: "multi-network-router.netbird.cloud",
        bytesRx: 12_000_000_000,
        bytesTx: 8_000_000_000,
        latencyMs: 31,
        relayAddress: "",
        lastHandshakeUnix: SECONDS(2),
        rosenpassEnabled: false,
        networks: [
            "10.0.0.0/8",
            "172.16.0.0/12",
            "192.168.0.0/16",
            "100.100.0.0/16",
            "10.50.50.0/24",
            "2001:db8::/32",
        ],
    }),
    new PeerStatus({
        ip: "100.64.0.10",
        pubKey: "MockKeyA000000000000000000000000000000000000=",
        connStatus: "Idle",
        connStatusUpdateUnix: MINUTES(45),
        relayed: false,
        localIceCandidateType: "",
        remoteIceCandidateType: "",
        localIceCandidateEndpoint: "",
        remoteIceCandidateEndpoint: "",
        fqdn: "a.nb",
        bytesRx: 0,
        bytesTx: 0,
        latencyMs: 0,
        relayAddress: "",
        lastHandshakeUnix: MINUTES(45),
        rosenpassEnabled: false,
        networks: [],
    }),
    // IPv6-NetBird-IP peer: the daemon assigns a v6 ULA inside fd00::/8 when
    // running on a v6-native overlay. Exercises the row layout when the IP
    // column is wide.
    new PeerStatus({
        ip: "fd00:1234:5678:abcd::42",
        pubKey: "MockKeyV6Native0000000000000000000000000000=",
        connStatus: "Connected",
        connStatusUpdateUnix: MINUTES(20),
        relayed: false,
        localIceCandidateType: "host",
        remoteIceCandidateType: "host",
        localIceCandidateEndpoint: "[2001:db8:cafe:0001::10]:51820",
        remoteIceCandidateEndpoint: "[2001:db8:cafe:0002::20]:51820",
        fqdn: "ipv6-overlay-peer.netbird.cloud",
        bytesRx: 800_000_000,
        bytesTx: 950_000_000,
        latencyMs: 41,
        relayAddress: "",
        lastHandshakeUnix: SECONDS(7),
        rosenpassEnabled: false,
        networks: ["2001:db8:1::/48", "2001:db8:2::/48", "fc00:dead:beef::/48"],
    }),
    // Dual-stack peer with mixed IPv4 / IPv6 ICE endpoints to test rows
    // where local and remote columns differ in width.
    new PeerStatus({
        ip: "100.64.0.11",
        pubKey: "MockKeyDualStack0000000000000000000000000000=",
        connStatus: "Connected",
        connStatusUpdateUnix: MINUTES(10),
        relayed: false,
        localIceCandidateType: "host",
        remoteIceCandidateType: "srflx",
        localIceCandidateEndpoint: "10.0.0.99:51820",
        remoteIceCandidateEndpoint: "[2606:4700:4700:0000:0000:0000:0000:1111]:51820",
        fqdn: "dual-stack.netbird.cloud",
        bytesRx: 320_000_000,
        bytesTx: 410_000_000,
        latencyMs: 28,
        relayAddress: "",
        lastHandshakeUnix: SECONDS(14),
        rosenpassEnabled: false,
        networks: ["10.20.30.0/24", "2001:db8:beef::/48"],
    }),
];

// Resources / routed networks. Mixes the three resource types the UI knows
// about (host = /32 or /128, subnet, domain) plus a deliberately overlapping
// pair to exercise the "overlapping" badge in NetworkFilters.
export const mockNetworkRoutes: Network[] = [
    new Network({
        id: "host-jenkins",
        range: "10.0.0.1/32",
        selected: true,
        domains: [],
        resolvedIps: {},
    }),
    new Network({
        id: "subnet-corp-lan",
        range: "192.168.1.0/24",
        selected: true,
        domains: [],
        resolvedIps: {},
    }),
    new Network({
        id: "subnet-wide-internal",
        range: "10.0.0.0/8",
        selected: false,
        domains: [],
        resolvedIps: {},
    }),
    new Network({
        id: "subnet-overlap-a",
        range: "172.16.0.0/16",
        selected: true,
        domains: [],
        resolvedIps: {},
    }),
    new Network({
        id: "subnet-overlap-b",
        range: "172.16.0.0/16",
        selected: false,
        domains: [],
        resolvedIps: {},
    }),
    new Network({
        id: "dns-example",
        range: "invalid Prefix",
        selected: true,
        domains: ["example.com"],
        resolvedIps: { "example.com": ["93.184.216.34"] },
    }),
    new Network({
        id: "dns-very-long-internal-domain-with-many-segments",
        range: "invalid Prefix",
        selected: false,
        domains: [
            "very-long-internal-service-name.dev.subdomain.example-company.internal",
            "another-long-domain-for-overflow-testing.example-company.internal",
            "third-long-domain-in-the-list.example-company.internal",
        ],
        resolvedIps: {
            "very-long-internal-service-name.dev.subdomain.example-company.internal": [
                "10.20.30.40",
                "10.20.30.41",
            ],
        },
    }),
    new Network({
        id: "ipv6-host",
        range: "2001:db8::1/128",
        selected: false,
        domains: [],
        resolvedIps: {},
    }),
    new Network({
        id: "ipv6-subnet-corp",
        range: "2001:db8:abcd::/48",
        selected: true,
        domains: [],
        resolvedIps: {},
    }),
    new Network({
        id: "ipv6-subnet-large",
        range: "fc00:dead:beef::/32",
        selected: false,
        domains: [],
        resolvedIps: {},
    }),
    new Network({
        id: "dns-dual-stack",
        range: "invalid Prefix",
        selected: true,
        domains: ["dual-stack.internal.example.com"],
        resolvedIps: {
            "dual-stack.internal.example.com": [
                "10.20.30.40",
                "10.20.30.41",
                "2001:db8:abcd::40",
                "2001:db8:abcd::41",
            ],
        },
    }),
    new Network({
        id: "dns-ipv6-only",
        range: "invalid Prefix",
        selected: false,
        domains: ["ipv6-only-service.example.com"],
        resolvedIps: {
            "ipv6-only-service.example.com": ["2606:4700:4700::1111", "2606:4700:4700::1001"],
        },
    }),
];

// Exit nodes are radio-style (mutually exclusive in the UI). Include one
// selected and one absurdly-long-id to test row truncation.
export const mockExitNodes: Network[] = [
    new Network({
        id: "us-east-1",
        range: "0.0.0.0/0",
        selected: false,
        domains: [],
        resolvedIps: {},
    }),
    new Network({
        id: "eu-central-frankfurt-primary",
        range: "0.0.0.0/0",
        selected: true,
        domains: [],
        resolvedIps: {},
    }),
    new Network({
        id: "very-long-exit-node-region-identifier-with-multiple-segments-and-numbers-12345-test",
        range: "0.0.0.0/0",
        selected: false,
        domains: [],
        resolvedIps: {},
    }),
    new Network({
        id: "ap-southeast-2",
        range: "0.0.0.0/0",
        selected: false,
        domains: [],
        resolvedIps: {},
    }),
];
