import * as plugins from './plugins.js';
import { TsView } from './tsview.classes.tsview.js';

/**
 * CLI handler for tsview
 */
export class TsViewCli {
  private smartcli: plugins.smartcli.Smartcli;

  constructor() {
    this.smartcli = new plugins.smartcli.Smartcli();
  }

  /**
   * Run the CLI
   */
  public async run(): Promise<void> {
    // Default command (no arguments)
    this.smartcli.standardCommand().subscribe(async (argvArg) => {
      await this.startViewer({
        port: argvArg.port as number | undefined,
        storageOnly: false,
        mongoOnly: false,
      });
    });

    // S3-only command
    const s3Command = this.smartcli.addCommand('s3');
    s3Command.subscribe(async (argvArg) => {
      await this.startViewer({
        port: argvArg.port as number | undefined,
        storageOnly: true,
        mongoOnly: false,
      });
    });

    // MongoDB-only command
    const mongoCommand = this.smartcli.addCommand('mongo');
    mongoCommand.subscribe(async (argvArg) => {
      await this.startViewer({
        port: argvArg.port as number | undefined,
        storageOnly: false,
        mongoOnly: true,
      });
    });

    // Alias for mongo command
    this.smartcli.addCommandAlias('mongo', 'mongodb');

    // Start parsing
    await this.smartcli.startParse();
  }

  /**
   * Start the viewer
   */
  private async startViewer(options: {
    port?: number;
    storageOnly: boolean;
    mongoOnly: boolean;
  }): Promise<void> {
    console.log('Starting TsView...');

    const viewer = new TsView();

    // Load config from env.json
    await viewer.loadConfigFromEnv();

    // Check what's configured
    const hasStorage = viewer.config.hasStorage();
    const hasMongo = viewer.config.hasMongo();

    if (!hasStorage && !hasMongo) {
      console.error('Error: No S3 or MongoDB configuration found.');
      console.error('Please create .nogit/env.json with your configuration.');
      console.error('');
      console.error('Example .nogit/env.json:');
      console.error(JSON.stringify({
        S3_ENDPOINT: 'localhost',
        S3_PORT: '9000',
        S3_ACCESSKEY: 'minioadmin',
        S3_SECRETKEY: 'minioadmin',
        S3_USESSL: false,
        MONGODB_URL: 'mongodb://localhost:27017',
        MONGODB_NAME: 'mydb',
      }, null, 2));
      process.exit(1);
    }

    if (options.storageOnly && !hasStorage) {
      console.error('Error: S3 configuration not found in .nogit/env.json');
      process.exit(1);
    }

    if (options.mongoOnly && !hasMongo) {
      console.error('Error: MongoDB configuration not found in .nogit/env.json');
      process.exit(1);
    }

    // Log what's available
    if (hasStorage) {
      console.log('S3 storage configured');
    }
    if (hasMongo) {
      console.log('MongoDB configured');
    }

    // Start the server
    const port = await viewer.start(options.port);

    // Keep process running
    console.log(`Press Ctrl+C to stop`);

    // Handle graceful shutdown
    process.on('SIGINT', async () => {
      console.log('\nShutting down...');
      await viewer.stop();
      process.exit(0);
    });

    process.on('SIGTERM', async () => {
      console.log('\nShutting down...');
      await viewer.stop();
      process.exit(0);
    });
  }
}
