import assert from "node:assert/strict"
import {
  detectWgConfigFormat,
  generateMikrotikRsc,
  generateNativeConf,
  parseMikrotikRsc,
  parseNativeConf,
  parseWgConfig,
} from "./wireguard-config.js"

const sampleConf = `[Interface]
PrivateKey = aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa=
Address = 10.210.0.1/30
ListenPort = 13231
MTU = 1420

[Peer]
PublicKey = bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb=
AllowedIPs = 10.210.0.2/32, 192.168.20.0/24
Endpoint = 10.0.1.1:13231
PersistentKeepalive = 25
`

const parsedConf = parseNativeConf(sampleConf)
assert.equal(parsedConf.format, "conf")
assert.equal(parsedConf.interface.listenPort, 13231)
assert.equal(parsedConf.interface.address, "10.210.0.1/30")
assert.equal(parsedConf.peers.length, 1)
assert.equal(parsedConf.peers[0]?.endpointAddress, "10.0.1.1")
assert.equal(parsedConf.peers[0]?.endpointPort, 13231)
assert.deepEqual(parsedConf.peers[0]?.allowedAddresses, ["10.210.0.2/32", "192.168.20.0/24"])

const roundConf = generateNativeConf({
  name: "wg0",
  listenPort: parsedConf.interface.listenPort ?? 13231,
  mtu: parsedConf.interface.mtu ?? 1420,
  privateKey: parsedConf.interface.privateKey,
  address: parsedConf.interface.address,
  peers: parsedConf.peers.map((p) => ({
    publicKey: p.publicKey,
    allowedIps: p.allowedAddresses,
    endpoint: p.endpointAddress
      ? `${p.endpointAddress}:${p.endpointPort ?? 13231}`
      : undefined,
    persistentKeepalive: p.persistentKeepalive,
  })),
})
const reparsed = parseNativeConf(roundConf)
assert.equal(reparsed.interface.privateKey, parsedConf.interface.privateKey)
assert.equal(reparsed.peers[0]?.publicKey, parsedConf.peers[0]?.publicKey)

const sampleRsc = `# WireGuard
/interface wireguard add \\
  name=wg-msk-spb \\
  listen-port=13231 \\
  mtu=1420 \\
  comment="MSK → SPB"

/ip address add \\
  address=10.210.0.1/30 \\
  interface=wg-msk-spb

/interface wireguard peers add \\
  interface=wg-msk-spb \\
  public-key="SPBPublicKeyBase64AAAAAAAAAAAAAAAAAAAAAA=" \\
  allowed-address=10.210.0.2/32,192.168.20.0/24 \\
  endpoint-address=10.0.1.1 \\
  endpoint-port=13231 \\
  persistent-keepalive=25
`

assert.equal(detectWgConfigFormat(sampleRsc), "rsc")
assert.equal(detectWgConfigFormat(sampleConf), "conf")

const parsedRsc = parseMikrotikRsc(sampleRsc)
assert.equal(parsedRsc.interface.name, "wg-msk-spb")
assert.equal(parsedRsc.interface.address, "10.210.0.1/30")
assert.equal(parsedRsc.peers.length, 1)
assert.equal(parsedRsc.peers[0]?.endpointPort, 13231)

const generatedRsc = generateMikrotikRsc({
  name: parsedRsc.interface.name,
  listenPort: parsedRsc.interface.listenPort ?? 13231,
  mtu: parsedRsc.interface.mtu ?? 1420,
  comment: parsedRsc.interface.comment,
  address: parsedRsc.interface.address,
  peers: parsedRsc.peers.map((p) => ({
    publicKey: p.publicKey,
    allowedIps: p.allowedAddresses,
    endpoint: p.endpointAddress
      ? `${p.endpointAddress}:${p.endpointPort ?? 13231}`
      : undefined,
    persistentKeepalive: p.persistentKeepalive,
  })),
})
const rscAgain = parseWgConfig(generatedRsc, "rsc")
assert.equal(rscAgain.interface.name, "wg-msk-spb")
assert.equal(rscAgain.peers[0]?.publicKey, parsedRsc.peers[0]?.publicKey)

console.log("wireguard-config tests ok")
