import { Pool } from 'pg';

const pool = new Pool({
  user: process.env.DB_USER || 'llm',
  password: process.env.DB_PASSWORD || 'llm_secure_2026',
  host: process.env.DB_HOST || '192.168.178.82',
  port: parseInt(process.env.DB_PORT || '5432'),
  database: process.env.DB_NAME || 'llm_gateway',
});

export interface RpkiValidationResult {
  status: 'valid' | 'invalid' | 'not-found' | 'unknown';
  prefix?: string;
  asn?: number;
  max_length?: number;
  expires?: string;
  description: string;
}

/**
 * Validate prefix + origin ASN against local RPKI ROA database
 * Returns VALID/INVALID/NOT-FOUND/UNKNOWN status
 */
export async function validateRpki(prefix: string, originAsn: number): Promise<RpkiValidationResult> {
  try {
    // Parse CIDR prefix to extract base prefix and length
    const prefixParts = prefix.split('/');
    if (prefixParts.length !== 2) {
      return { status: 'unknown', description: 'Invalid CIDR format' };
    }

    const prefixLength = parseInt(prefixParts[1]);

    // Query for covering ROAs
    const result = await pool.query(
      `SELECT * FROM rpki_roas
       WHERE $1::cidr << (prefix || '/' || max_length)::cidr
       AND origin_asn = $2
       AND expires > NOW()
       LIMIT 10`,
      [prefix, originAsn]
    );

    if (result.rows.length === 0) {
      // Check if any ROAs exist for this prefix at all
      const anyRoa = await pool.query(
        `SELECT 1 FROM rpki_roas WHERE $1::cidr << prefix AND expires > NOW() LIMIT 1`,
        [prefix]
      );

      if (anyRoa.rows.length > 0) {
        return {
          status: 'invalid',
          prefix,
          asn: originAsn,
          description: `RPKI INVALID: ROAs exist for this prefix but origin ASN ${originAsn} is not authorized`,
        };
      }

      return {
        status: 'not-found',
        prefix,
        asn: originAsn,
        description: 'No matching ROA found (route is unprotected)',
      };
    }

    // Validate prefix length against max_length
    const roa = result.rows[0];
    if (prefixLength > roa.max_length) {
      return {
        status: 'invalid',
        prefix,
        asn: originAsn,
        max_length: roa.max_length,
        description: `RPKI INVALID: Prefix length ${prefixLength} exceeds max_length ${roa.max_length}`,
      };
    }

    return {
      status: 'valid',
      prefix,
      asn: originAsn,
      max_length: roa.max_length,
      expires: roa.expires,
      description: `RPKI VALID: Origin ASN ${originAsn} authorized for ${prefix}`,
    };
  } catch (error) {
    console.error('[RPKI Client] Error validating RPKI:', error);
    return { status: 'unknown', description: 'RPKI validation error' };
  }
}

/**
 * Get all ROAs for a given ASN
 */
export async function getRoasForAsn(asn: number) {
  try {
    const result = await pool.query(
      `SELECT prefix, max_length, expires FROM rpki_roas
       WHERE origin_asn = $1 AND expires > NOW()
       ORDER BY prefix`,
      [asn]
    );
    return result.rows;
  } catch (error) {
    console.error('[RPKI Client] Error querying ROAs:', error);
    return [];
  }
}

/**
 * Get RPKI statistics
 */
export async function getRpkiStats() {
  try {
    const result = await pool.query(`
      SELECT
        COUNT(*) as total_roas,
        COUNT(DISTINCT origin_asn) as covered_asns,
        MAX(expires) as latest_expiry,
        COUNT(CASE WHEN expires < NOW() THEN 1 END) as expired_roas
      FROM rpki_roas
    `);
    return result.rows[0] || null;
  } catch (error) {
    console.error('[RPKI Client] Error querying stats:', error);
    return null;
  }
}

export async function cleanup() {
  await pool.end();
}
