import { promises as fs } from 'fs';
import { homedir } from 'os';
import { join } from 'path';
import log from 'electron-log';
import https from 'https';

export interface GemrcConfig {
  exists: boolean;
  configured: boolean;
  sources: string[];
  hasArtifactorySource: boolean;
  username?: string;
  token?: string;
  credentialsValid?: boolean;
  credentialsValidationError?: string;
}

/**
 * Validate Artifactory credentials by making an HTTP request
 */
async function validateArtifactoryCredentials(username: string, token: string): Promise<{ valid: boolean; error?: string }> {
  return new Promise((resolve) => {
    const url = `https://${username}:${token}@instructure.jfrog.io/artifactory/api/gems/internal-gems/`;

    log.info('Validating Artifactory credentials...');

    const request = https.get(url, { timeout: 10000 }, (res) => {
      log.info(`Artifactory credential validation response: ${res.statusCode}`);

      if (res.statusCode === 200) {
        resolve({ valid: true });
      } else if (res.statusCode === 401 || res.statusCode === 403) {
        resolve({ valid: false, error: 'Invalid credentials - Authentication failed' });
      } else {
        resolve({ valid: false, error: `Unexpected response: ${res.statusCode}` });
      }

      // Consume response data to free up memory
      res.resume();
    });

    request.on('error', (err) => {
      log.warn('Error validating Artifactory credentials:', err.message);
      resolve({ valid: false, error: `Network error: ${err.message}` });
    });

    request.on('timeout', () => {
      request.destroy();
      log.warn('Artifactory credential validation timed out');
      resolve({ valid: false, error: 'Connection timeout' });
    });
  });
}

/**
 * Parse sources from .gemrc YAML content
 */
function parseYamlSources(content: string): string[] {
  const sources: string[] = [];
  const lines = content.split('\n');
  let inSourcesSection = false;

  for (const line of lines) {
    if (line.trim() === ':sources:') {
      inSourcesSection = true;
      continue;
    }

    if (inSourcesSection) {
      // Check if line starts with '- ' (YAML list item)
      const match = line.match(/^\s*-\s+(.+)$/);
      if (match) {
        sources.push(match[1].trim());
      } else if (line.trim() && !line.startsWith(' ') && !line.startsWith('-')) {
        // End of sources section if we hit a non-indented, non-list line
        break;
      }
    }
  }

  return sources;
}

/**
 * Check the status of the .gemrc file
 */
export async function checkGemrcStatus(): Promise<GemrcConfig> {
  const gemrcPath = join(homedir(), '.gemrc');

  try {
    const content = await fs.readFile(gemrcPath, 'utf-8');
    const hasArtifactory = content.includes('instructure.jfrog.io/artifactory/api/gems/internal-gems/');
    const sources = parseYamlSources(content);

    let username: string | undefined;
    let token: string | undefined;
    let credentialsValid: boolean | undefined;
    let credentialsValidationError: string | undefined;

    if (hasArtifactory) {
      // Find the Artifactory source and extract username/token
      const artifactorySource = sources.find(
        s => s.includes('instructure.jfrog.io/artifactory/api/gems/internal-gems/')
      );

      if (artifactorySource) {
        // Parse URL format: https://username:token@instructure.jfrog.io/...
        const match = artifactorySource.match(/https:\/\/([^:]+):([^@]+)@/);
        if (match) {
          username = match[1];
          token = match[2];

          // Validate credentials
          const validationResult = await validateArtifactoryCredentials(username, token);
          credentialsValid = validationResult.valid;
          credentialsValidationError = validationResult.error;
        }
      }
    }

    return {
      exists: true,
      configured: hasArtifactory,
      sources,
      hasArtifactorySource: hasArtifactory,
      username,
      token,
      credentialsValid,
      credentialsValidationError
    };
  } catch (error: any) {
    if (error.code === 'ENOENT') {
      log.info('.gemrc file does not exist');
      return {
        exists: false,
        configured: false,
        sources: [],
        hasArtifactorySource: false
      };
    }
    log.error('Error reading .gemrc file:', error);
    throw error;
  }
}

/**
 * Create a new .gemrc file with Artifactory source
 */
export async function createGemrc(username: string, token: string): Promise<void> {
  const gemrcPath = join(homedir(), '.gemrc');
  const content = `---
:sources:
- https://${username}:${token}@instructure.jfrog.io/artifactory/api/gems/internal-gems/
- https://rubygems.org/
`;

  await fs.writeFile(gemrcPath, content, 'utf-8');
  log.info('Created .gemrc file');
}

/**
 * Update existing .gemrc file with Artifactory source
 */
export async function updateGemrc(username: string, token: string): Promise<void> {
  const gemrcPath = join(homedir(), '.gemrc');
  const artifactorySource = `https://${username}:${token}@instructure.jfrog.io/artifactory/api/gems/internal-gems/`;

  try {
    const content = await fs.readFile(gemrcPath, 'utf-8');
    const lines = content.split('\n');
    const newLines: string[] = [];
    let inSourcesSection = false;
    let artifactoryAdded = false;
    let sourcesLineIndex = -1;

    for (let i = 0; i < lines.length; i++) {
      const line = lines[i];

      if (line.trim() === ':sources:') {
        inSourcesSection = true;
        sourcesLineIndex = newLines.length;
        newLines.push(line);
        continue;
      }

      if (inSourcesSection) {
        // Check if this line is an Artifactory source
        if (line.includes('instructure.jfrog.io/artifactory/api/gems/internal-gems/')) {
          // Replace with new credentials
          newLines.push(`- ${artifactorySource}`);
          artifactoryAdded = true;
          continue;
        }

        // Check if line is a source item
        const match = line.match(/^\s*-\s+(.+)$/);
        if (match) {
          // If we haven't added Artifactory yet, add it before other sources
          if (!artifactoryAdded) {
            newLines.push(`- ${artifactorySource}`);
            artifactoryAdded = true;
          }
          newLines.push(line);
        } else if (line.trim() && !line.startsWith(' ') && !line.startsWith('-')) {
          // End of sources section
          if (!artifactoryAdded) {
            newLines.push(`- ${artifactorySource}`);
            artifactoryAdded = true;
          }
          inSourcesSection = false;
          newLines.push(line);
        } else {
          newLines.push(line);
        }
      } else {
        newLines.push(line);
      }
    }

    // If we're still in sources section at end and haven't added Artifactory
    if (inSourcesSection && !artifactoryAdded) {
      newLines.push(`- ${artifactorySource}`);
    }

    // If there was no sources section, add one
    if (sourcesLineIndex === -1) {
      newLines.unshift(':sources:');
      newLines.splice(1, 0, `- ${artifactorySource}`);
      newLines.splice(2, 0, '- https://rubygems.org/');
    }

    await fs.writeFile(gemrcPath, newLines.join('\n'), 'utf-8');
    log.info('Updated .gemrc file with Artifactory source');
  } catch (error: any) {
    log.error('Error updating .gemrc file:', error);
    throw error;
  }
}
