// SPDX-FileCopyrightText: 2026 FocusFlow contributors
// SPDX-License-Identifier: AGPL-3.0-only

/// Runs the Dev workspace script.
library;

import 'dart:io';

import 'package:scheduler_backup/backup.dart';

/// Starts local code generation and a Flutter desktop dev session.
Future<void> main(List<String> arguments) async {
  final sqlitePath =
      _option(arguments, '--sqlite') ?? defaultSchedulerSqliteFile().path;
  final device = _option(arguments, '--device') ?? _defaultDesktopDevice();

  stdout.writeln('SQLite path: $sqlitePath');
  final buildRunner = await _start(
    'dart',
    <String>[
      'run',
      'build_runner',
      'watch',
      '--delete-conflicting-outputs',
    ],
  );
  stdout.writeln('Started build_runner watch (pid ${buildRunner.pid}).');

  _watchForExit(ProcessSignal.sigint, 130, buildRunner);
  if (!Platform.isWindows) {
    _watchForExit(ProcessSignal.sigterm, 143, buildRunner);
  }

  try {
    final flutter = await _start(
      'flutter',
      <String>[
        'run',
        '-d',
        device,
        '--dart-define=SCHEDULER_SQLITE_PATH=$sqlitePath',
      ],
    );
    stdout.writeln(
        'Started Flutter desktop with hot reload (pid ${flutter.pid}).');
    exitCode = await flutter.exitCode;
  } finally {
    buildRunner.kill();
  }
}

/// Top-level helper that performs the `_watchForExit` operation for this file.
/// Keeping the helper private makes the surrounding flow easier to read while preventing unrelated libraries from depending on implementation detail.
void _watchForExit(ProcessSignal signal, int code, Process buildRunner) {
  signal.watch().listen((_) {
    buildRunner.kill();
    exit(code);
  });
}

/// Top-level helper that performs the `_start` operation for this file.
/// Keeping the helper private makes the surrounding flow easier to read while preventing unrelated libraries from depending on implementation detail.
Future<Process> _start(String executable, List<String> arguments) async {
  stdout.writeln('> $executable ${arguments.join(' ')}');
  try {
    return Process.start(
      executable,
      arguments,
      mode: ProcessStartMode.inheritStdio,
      runInShell: Platform.isWindows,
    );
  } on ProcessException catch (error) {
    stderr.writeln(error.message);
    stderr.writeln('Unable to start: $executable');
    rethrow;
  }
}

/// Top-level helper that performs the `_defaultDesktopDevice` operation for this file.
/// Keeping the helper private makes the surrounding flow easier to read while preventing unrelated libraries from depending on implementation detail.
String _defaultDesktopDevice() {
  if (Platform.isMacOS) return 'macos';
  if (Platform.isWindows) return 'windows';
  return 'linux';
}

/// Top-level helper that performs the `_option` operation for this file.
/// Keeping the helper private makes the surrounding flow easier to read while preventing unrelated libraries from depending on implementation detail.
String? _option(List<String> arguments, String name) {
  final index = arguments.indexOf(name);
  if (index == -1 || index + 1 >= arguments.length) {
    return null;
  }
  return arguments[index + 1];
}
