// tests/integration/federation/wire-codec.spec.ts
//
// Integration tests for DNS Hierarchical Wire Codec
// Per JOB-FEDERATION-GATEWAY-ARCHITECTURE - Simplified wire format
//
// DNS Format: {mount}.{component}.{plane}.{message}
// - Realm is a transport concern, not in the wire topic
// - No principal in wire format
// - No exec token in wire format

import { describe, it } from 'node:test';
import assert from 'node:assert';
import {
  mxesc1Encode,
  mxesc1Decode,
  encodeToWireTopic,
  decodeFromWireTopic,
} from '@open-matrix/federation';

describe('DNS Hierarchical Wire Codec', () => {

  // ═══════════════════════════════════════════════════════════════════════════
  // MXESC-1 Encoding (MATRIX-PROTOCOL-2 §8.3.1)
  // ═══════════════════════════════════════════════════════════════════════════

  describe('MXESC-1 encoding', () => {
    describe('safe characters pass through', () => {
      const safeChars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789._~-';

      it('preserves all safe characters', () => {
        assert.strictEqual(mxesc1Encode(safeChars), safeChars);
      });
    });

    describe('unsafe characters encoded', () => {
      // Note: '/' is safe in MXESC-1 (used as topic separator)
      const testCases = [
        { input: ':', expected: '%3A' },
        { input: ' ', expected: '%20' },
        { input: '%', expected: '%25' },
        { input: '@', expected: '%40' },
        { input: '#', expected: '%23' },
        { input: '?', expected: '%3F' },
        { input: '=', expected: '%3D' },
        { input: '&', expected: '%26' },
      ];

      for (const { input, expected } of testCases) {
        it(`encodes '${input}' as '${expected}'`, () => {
          assert.strictEqual(mxesc1Encode(input), expected);
        });
      }
    });

    describe('UTF-8 encoding', () => {
      const testCases = [
        { input: 'ü', expected: '%C3%BC' },        // U+00FC
        { input: '日', expected: '%E6%97%A5' },    // U+65E5
        { input: '🎉', expected: '%F0%9F%8E%89' }, // U+1F389
      ];

      for (const { input, expected } of testCases) {
        it(`encodes '${input}' as '${expected}'`, () => {
          assert.strictEqual(mxesc1Encode(input), expected);
        });
      }
    });

    describe('bijectivity', () => {
      const testInputs = [
        'hello',
        'hello world',
        'foo.bar',
        'über',
        '100%',
        'foo/bar/baz',
        'a:b:c',
        '日本語',
        'emoji🎉test',
        'path/with spaces/and:colons',
      ];

      for (const input of testInputs) {
        it(`roundtrips: '${input}'`, () => {
          const encoded = mxesc1Encode(input);
          const decoded = mxesc1Decode(encoded);
          assert.strictEqual(decoded, input);
        });
      }
    });
  });

  // ═══════════════════════════════════════════════════════════════════════════
  // Wire Topic Encoding - DNS Hierarchical Format
  // Format: {mount}.{component}.{plane}.{message}
  // Realm is a transport concern, not embedded in the topic.
  // ═══════════════════════════════════════════════════════════════════════════

  describe('encodeToWireTopic (DNS hierarchical)', () => {
    it('encodes simple command with mount segments', () => {
      const wire = encodeToWireTopic({
        realm: 'acme.com',
        mountSegments: ['env', 'prod', 'region', 'us-east', 'app', 'editor'],
        componentPath: 'app.editor.sidebar',
        plane: 'accepts',
        messageName: 'setText'
      });

      assert.strictEqual(wire,
        'env.prod.region.us-east.app.editor.app.editor.sidebar.accepts.setText'
      );
    });

    it('encodes emits topic', () => {
      const wire = encodeToWireTopic({
        realm: 'flowpad-demo',
        mountSegments: ['tree'],
        componentPath: 'tree.results',
        plane: 'emits',
        messageName: 'queryExecuted'
      });

      assert.strictEqual(wire, 'tree.tree.results.emits.queryExecuted');
    });

    it('encodes empty mount segments', () => {
      const wire = encodeToWireTopic({
        realm: 'test',
        mountSegments: [],
        componentPath: 'app',
        plane: 'accepts',
        messageName: 'ping'
      });

      assert.strictEqual(wire, 'app.accepts.ping');
    });

    it('encodes mount segments with dots', () => {
      const wire = encodeToWireTopic({
        realm: 'example.com',
        mountSegments: ['path-segment', 'sub'],
        componentPath: 'app',
        plane: 'accepts',
        messageName: 'test'
      });

      assert.strictEqual(wire, 'path-segment.sub.app.accepts.test');
    });

    it('encodes dotted message names', () => {
      const wire = encodeToWireTopic({
        realm: 'matrix-3',
        mountSegments: [],
        componentPath: 'tree',
        plane: 'emits',
        messageName: 'lifecycle.childAdded'
      });

      assert.strictEqual(wire, 'tree.emits.lifecycle.childAdded');
    });

    it('encodes with realm (realm not in output)', () => {
      const wire = encodeToWireTopic({
        realm: 'my-realm',
        mountSegments: [],
        componentPath: 'app',
        plane: 'accepts',
        messageName: 'test'
      });

      assert.strictEqual(wire, 'app.accepts.test');
    });
  });

  // ═══════════════════════════════════════════════════════════════════════════
  // Wire Topic Decoding - DNS Hierarchical Format
  // ═══════════════════════════════════════════════════════════════════════════

  describe('decodeFromWireTopic (DNS hierarchical)', () => {
    it('decodes simple command with mount segments', () => {
      const params = decodeFromWireTopic(
        'env.prod.app.editor.sidebar.accepts.setText'
      );

      assert.ok(params);
      assert.strictEqual(params.realm, '');
      assert.deepStrictEqual(params.mountSegments, ['env', 'prod', 'app', 'editor']);
      assert.strictEqual(params.componentPath, 'sidebar');
      assert.strictEqual(params.plane, 'accepts');
      assert.strictEqual(params.messageName, 'setText');
    });

    it('decodes command without mount', () => {
      const params = decodeFromWireTopic(
        'app.accepts.test'
      );

      assert.deepStrictEqual(params, {
        realm: '',
        mountSegments: [],
        componentPath: 'app',
        plane: 'accepts',
        messageName: 'test'
      });
    });

    it('decodes dotted message names', () => {
      const params = decodeFromWireTopic(
        'tree.emits.lifecycle.childAdded'
      );

      assert.ok(params);
      assert.strictEqual(params.messageName, 'lifecycle.childAdded');
    });

    it('returns null for topic without plane', () => {
      assert.strictEqual(decodeFromWireTopic('invalid-topic'), null);
      assert.strictEqual(decodeFromWireTopic('just.segments'), null);
    });

    it('returns null for invalid plane', () => {
      assert.strictEqual(decodeFromWireTopic('app.invalid.test'), null);
    });
  });

  // ═══════════════════════════════════════════════════════════════════════════
  // Roundtrip Tests
  // ═══════════════════════════════════════════════════════════════════════════

  describe('roundtrip encode/decode', () => {
    const testCases = [
      {
        realm: 'acme.com',
        mountSegments: ['env', 'prod'],
        componentPath: 'editor',
        plane: 'accepts' as const,
        messageName: 'test'
      },
      {
        realm: 'flowpad-demo',
        mountSegments: [],
        componentPath: 'tree',
        plane: 'emits' as const,
        messageName: 'ready'
      },
      {
        realm: 'example.com',
        mountSegments: ['projects', 'myproject'],
        componentPath: 'file',
        plane: 'accepts' as const,
        messageName: 'read'
      },
      {
        realm: 'matrix-3',
        mountSegments: ['daemon', 'project'],
        componentPath: 'tree',
        plane: 'emits' as const,
        messageName: 'lifecycle.childAdded'
      },
    ];

    for (const params of testCases) {
      const desc = `${params.componentPath}.${params.plane}.${params.messageName}`;
      it(`roundtrips: ${desc}`, () => {
        const encoded = encodeToWireTopic(params);
        const decoded = decodeFromWireTopic(encoded);

        assert.ok(decoded);
        // Realm is a transport concern — not embedded in topic, always ''
        assert.strictEqual(decoded.realm, '');
        assert.deepStrictEqual(decoded.mountSegments, params.mountSegments);
        assert.strictEqual(decoded.componentPath, params.componentPath);
        assert.strictEqual(decoded.plane, params.plane);
        assert.strictEqual(decoded.messageName, params.messageName);
      });
    }
  });
});
