import * as path from 'path';
import { tap, expect } from '@git.zone/tstest/tapbundle';

import { SmartProxy } from '../ts/proxies/smart-proxy/index.js';
import {
  createHttpRoute,
  createHttpsTerminateRoute,
  createHttpsPassthroughRoute,
  createHttpToHttpsRedirect,
  createCompleteHttpsServer,
  createLoadBalancerRoute,
  createApiRoute,
  createWebSocketRoute
} from '../ts/proxies/smart-proxy/utils/route-helpers.js';
import type { IRouteConfig } from '../ts/proxies/smart-proxy/models/route-types.js';

// Test to demonstrate various route configurations using the new helpers
tap.test('Route-based configuration examples', async (tools) => {
  // Example 1: HTTP-only configuration
  const httpOnlyRoute = createHttpRoute(
    'http.example.com',
    {
      host: 'localhost',
      port: 3000
    },
    {
      name: 'Basic HTTP Route'
    }
  );

  console.log('HTTP-only route created successfully:', httpOnlyRoute.name);
  expect(httpOnlyRoute.action.type).toEqual('forward');
  expect(httpOnlyRoute.match.domains).toEqual('http.example.com');

  // Example 2: HTTPS Passthrough (SNI) configuration
  const httpsPassthroughRoute = createHttpsPassthroughRoute(
    'pass.example.com',
    {
      host: ['10.0.0.1', '10.0.0.2'], // Round-robin target IPs
      port: 443
    },
    {
      name: 'HTTPS Passthrough Route'
    }
  );

  expect(httpsPassthroughRoute).toBeTruthy();
  expect(httpsPassthroughRoute.action.tls?.mode).toEqual('passthrough');
  expect(Array.isArray(httpsPassthroughRoute.action.target?.host)).toBeTrue();

  // Example 3: HTTPS Termination to HTTP Backend
  const terminateToHttpRoute = createHttpsTerminateRoute(
    'secure.example.com',
    {
      host: 'localhost',
      port: 8080
    },
    {
      certificate: 'auto',
      name: 'HTTPS Termination to HTTP Backend'
    }
  );

  // Create the HTTP to HTTPS redirect for this domain
  const httpToHttpsRedirect = createHttpToHttpsRedirect(
    'secure.example.com',
    443,
    {
      name: 'HTTP to HTTPS Redirect for secure.example.com'
    }
  );

  expect(terminateToHttpRoute).toBeTruthy();
  expect(terminateToHttpRoute.action.tls?.mode).toEqual('terminate');
  expect(httpToHttpsRedirect.action.type).toEqual('socket-handler');

  // Example 4: Load Balancer with HTTPS
  const loadBalancerRoute = createLoadBalancerRoute(
    'proxy.example.com',
    ['internal-api-1.local', 'internal-api-2.local'],
    8443,
    {
      tls: {
        mode: 'terminate-and-reencrypt',
        certificate: 'auto'
      },
      name: 'Load Balanced HTTPS Route'
    }
  );

  expect(loadBalancerRoute).toBeTruthy();
  expect(loadBalancerRoute.action.tls?.mode).toEqual('terminate-and-reencrypt');
  expect(Array.isArray(loadBalancerRoute.action.target?.host)).toBeTrue();

  // Example 5: API Route
  const apiRoute = createApiRoute(
    'api.example.com',
    '/api',
    { host: 'localhost', port: 8081 },
    {
      name: 'API Route',
      useTls: true,
      addCorsHeaders: true
    }
  );

  expect(apiRoute.action.type).toEqual('forward');
  expect(apiRoute.match.path).toBeTruthy();

  // Example 6: Complete HTTPS Server with HTTP Redirect
  const httpsServerRoutes = createCompleteHttpsServer(
    'complete.example.com',
    {
      host: 'localhost',
      port: 8080
    },
    {
      certificate: 'auto',
      name: 'Complete HTTPS Server'
    }
  );

  expect(Array.isArray(httpsServerRoutes)).toBeTrue();
  expect(httpsServerRoutes.length).toEqual(2); // HTTPS route and HTTP redirect
  expect(httpsServerRoutes[0].action.tls?.mode).toEqual('terminate');
  expect(httpsServerRoutes[1].action.type).toEqual('socket-handler');

  // Example 7: Static File Server - removed (use nginx/apache behind proxy)

  // Example 8: WebSocket Route
  const webSocketRoute = createWebSocketRoute(
    'ws.example.com',
    '/ws',
    { host: 'localhost', port: 8082 },
    {
      useTls: true,
      name: 'WebSocket Route'
    }
  );

  expect(webSocketRoute.action.type).toEqual('forward');
  expect(webSocketRoute.action.websocket?.enabled).toBeTrue();

  // Create a SmartProxy instance with all routes
  const allRoutes: IRouteConfig[] = [
    httpOnlyRoute,
    httpsPassthroughRoute,
    terminateToHttpRoute,
    httpToHttpsRedirect,
    loadBalancerRoute,
    apiRoute,
    ...httpsServerRoutes,
    webSocketRoute
  ];

  // We're not actually starting the SmartProxy in this test,
  // just verifying that the configuration is valid
  const smartProxy = new SmartProxy({
    routes: allRoutes
  });

  // Just verify that all routes are configured correctly
  console.log(`Created ${allRoutes.length} example routes`);
  expect(allRoutes.length).toEqual(9); // One less without static file route
});

export default tap.start();