#!/usr/bin/env node

/**
 * Test Different Pangolin Raw Resource Creation Configurations
 *
 * Goal: Determine correct payload format for HTTP resources
 *
 * Tests:
 * 1. Current payload (fails with "Unrecognized keys: type, ssl, enabled")
 * 2. Payload without `type` field
 * 3. Payload with only name, domainId, subdomain, http: true
 * 4. Payload with `protocol: "http"` instead of `type: "http"`
 * 5. TCP resource to understand base payload format
 * 6. Minimal HTTP resource payload
 * 7. Check actual resource structure from listResources()
 */

import { pangolinClient, CreateResourcePayload, PangolinResource } from './src/services/pangolin.client';
import { logger } from './src/utils/logger';

const orgId = process.env.PANGOLIN_ORG_ID || '';
const apiUrl = process.env.PANGOLIN_API_URL || '';
const apiKey = process.env.PANGOLIN_API_KEY || '';

if (!orgId || !apiUrl || !apiKey) {
  logger.error('Missing required env vars: PANGOLIN_ORG_URL, PANGOLIN_API_KEY, PANGOLIN_ORG_ID');
  process.exit(1);
}

logger.info('=== Pangolin Resource Payload Test ===');
logger.info(`OrgId: ${orgId}`);
logger.info(`API URL: ${apiUrl}`);
logger.info('');

// Helper to make raw requests
async function rawRequest(method: string, path: string, body?: unknown): Promise<unknown> {
  const url = `${apiUrl}${path}`;
  logger.info(`[${method}] ${url}`);
  if (body) {
    logger.info(`Body: ${JSON.stringify(body, null, 2)}`);
  }

  try {
    const res = await fetch(url, {
      method,
      headers: {
        'Authorization': `Bearer ${apiKey}`,
        'Content-Type': 'application/json',
      },
      body: body ? JSON.stringify(body) : undefined,
    });

    const text = await res.text();
    logger.info(`Response Status: ${res.status}`);

    if (text) {
      try {
        const json = JSON.parse(text);
        logger.info(`Response: ${JSON.stringify(json, null, 2)}`);
        return json;
      } catch (e) {
        logger.info(`Response (text): ${text}`);
        return text;
      }
    }
    return undefined;
  } catch (err) {
    logger.error(`Request failed: ${err instanceof Error ? err.message : String(err)}`);
    return undefined;
  }
}

async function testListExistingResources() {
  logger.info('\n--- Test 0: List Existing Resources ---');
  const resources = await pangolinClient.listResources();
  logger.info(`Found ${resources.length} resources`);
  if (resources.length > 0) {
    logger.info('Sample resource structure:');
    logger.info(JSON.stringify(resources[0], null, 2));
  }
}

async function testPayload1() {
  logger.info('\n--- Test 1: Current Payload (WITH type, ssl, enabled) ---');
  logger.info('Expected error: "Unrecognized keys: type, ssl, enabled"');

  const payload = {
    name: 'Test HTTP 1',
    type: 'http',
    domainId: 'test-domain-id',
    subdomain: 'test1',
    http: true,
    ssl: true,
    enabled: true,
  };

  await rawRequest('PUT', `/org/${orgId}/site-resource`, payload);
}

async function testPayload2() {
  logger.info('\n--- Test 2: Payload WITHOUT type field ---');
  logger.info('Maybe endpoint determines type from other fields');

  const payload = {
    name: 'Test HTTP 2',
    domainId: 'test-domain-id',
    subdomain: 'test2',
    http: true,
  };

  await rawRequest('PUT', `/org/${orgId}/site-resource`, payload);
}

async function testPayload3() {
  logger.info('\n--- Test 3: Minimal Payload (name, domainId, subdomain, http) ---');

  const payload = {
    name: 'Test HTTP 3',
    domainId: 'test-domain-id',
    subdomain: 'test3',
    http: true,
  };

  await rawRequest('PUT', `/org/${orgId}/site-resource`, payload);
}

async function testPayload4() {
  logger.info('\n--- Test 4: Payload with protocol instead of type ---');

  const payload = {
    name: 'Test HTTP 4',
    domainId: 'test-domain-id',
    subdomain: 'test4',
    protocol: 'http',
  };

  await rawRequest('PUT', `/org/${orgId}/site-resource`, payload);
}

async function testPayload5() {
  logger.info('\n--- Test 5: TCP Resource on /resource endpoint ---');
  logger.info('TCP uses `/org/{orgId}/resource` endpoint (different from /site-resource)');

  const payload = {
    name: 'Test TCP 1',
    type: 'tcp',
    proxyPort: 2222,
    stickySession: false,
    enabled: true,
  };

  await rawRequest('PUT', `/org/${orgId}/resource`, payload);
}

async function testPayload6() {
  logger.info('\n--- Test 6: Only Name + Subdomain (simplest) ---');

  const payload = {
    name: 'Test HTTP 6',
    subdomain: 'test6',
  };

  await rawRequest('PUT', `/org/${orgId}/site-resource`, payload);
}

async function testPayload7() {
  logger.info('\n--- Test 7: Check if siteId is required ---');

  // First get a valid siteId
  const sites = await pangolinClient.listSites();
  if (sites.length === 0) {
    logger.warn('No sites found - skipping test');
    return;
  }

  const siteId = sites[0].siteId;
  logger.info(`Using siteId: ${siteId}`);

  const payload = {
    name: 'Test HTTP 7',
    subdomain: 'test7',
    siteId,
  };

  await rawRequest('PUT', `/org/${orgId}/site-resource`, payload);
}

async function testPayload8() {
  logger.info('\n--- Test 8: Try on different endpoint (/org/{orgId}/resource) with http resource ---');

  const payload = {
    name: 'Test HTTP 8',
    domainId: 'test-domain-id',
    subdomain: 'test8',
    http: true,
  };

  await rawRequest('PUT', `/org/${orgId}/resource`, payload);
}

async function main() {
  try {
    // Check health first
    const healthy = await pangolinClient.healthCheck();
    if (!healthy) {
      logger.error('Pangolin API health check failed');
      process.exit(1);
    }
    logger.info('Pangolin API health check: OK');

    // Run tests
    await testListExistingResources();
    await testPayload1();
    await testPayload2();
    await testPayload3();
    await testPayload4();
    await testPayload5();
    await testPayload6();
    await testPayload7();
    await testPayload8();

    logger.info('\n=== Test Complete ===');
  } catch (err) {
    logger.error('Test failed:', err);
    process.exit(1);
  }
}

main().catch(err => {
  logger.error('Uncaught error:', err);
  process.exit(1);
});
