/// CLI entry point for the terminal Wolf3D host.
///
/// This executable locates bundled retail assets, constructs a [WolfEngine]
/// configured for terminal rendering, and then hands control to [CliGameLoop].
library;

import 'dart:io';

import 'package:wolf_3d_cli/cli_game_loop.dart';
import 'package:wolf_3d_cli/cli_renderer_settings_persistence.dart';
import 'package:wolf_3d_dart/wolf_3d_data.dart';
import 'package:wolf_3d_dart/wolf_3d_data_types.dart';
import 'package:wolf_3d_dart/wolf_3d_engine.dart';
import 'package:wolf_3d_dart/wolf_3d_input.dart';

/// Restores terminal state before exiting the process with [code].
void exitCleanly(int code) {
  stdout.write('\x1b[0m'); // Reset color
  stdout.write('\x1b[2J\x1b[H'); // Clear screen
  stdout.write('\x1b[?25h'); // SHOW the cursor again
  exit(code);
}

/// Launches the CLI renderer against the bundled retail asset set.
void main() async {
  stdout.write("Discovering game data...");
  // Resolve the asset package relative to this executable so the CLI can run
  // from the repo without additional configuration.
  final scriptUri = Platform.script;

  final targetUri = scriptUri.resolve(
    '../../../packages/wolf_3d_assets/assets/retail',
  );
  final targetPath = targetUri.toFilePath();

  final availableGames = await WolfensteinLoader.discover(
    directoryPath: targetPath,
    recursive: true,
  );

  if (availableGames.isEmpty) {
    stderr.writeln('\nNo Wolf3D game files were found at: $targetPath');
    stderr.writeln(
      'Please provide valid game data files before starting the CLI host.',
    );
    exitCleanly(1);
  }

  CliGameLoop? gameLoop;

  void stopAndExit(int code) {
    gameLoop?.stop();
    exitCleanly(code);
  }

  final engine = WolfEngine(
    availableGames: availableGames.values.toList(growable: false),
    startingEpisode: 0,
    frameBuffer: FrameBuffer(
      stdout.terminalColumns,
      stdout.terminalLines,
    ),
    input: CliInput(),
    onGameWon: () => stopAndExit(0),
    onQuit: () => stopAndExit(0),
  );

  engine.init();

  final persistence = CliRendererSettingsPersistence();
  final WolfRendererSettings? saved = await persistence.load();

  gameLoop = CliGameLoop(
    engine: engine,
    onExit: stopAndExit,
    persistence: persistence,
    initialSettings: saved,
  );

  await gameLoop.start();
}
