// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// Executable script to generate bindings for some C library.
import 'dart:io';

import 'package:args/args.dart';
import 'package:cli_util/cli_logging.dart' show Ansi;
import 'package:logging/logging.dart';
import 'package:package_config/package_config.dart';
import 'package:yaml/yaml.dart' as yaml;

import '../../ffigen.dart';

final _ansi = Ansi(Ansi.terminalSupportsAnsi);
final logger = () {
  final l = Logger('ffigen.ffigen');
  l.onRecord.listen((record) {
    final levelStr = '[${record.level.name}]'.padRight(9);
    final log = '$levelStr: ${record.message}';
    if (record.level < Level.SEVERE) {
      print(log);
    } else {
      print('${_ansi.red}$log${_ansi.none}');
    }
  });
  return l;
}();

const compilerOpts = 'compiler-opts';
const ignoreSourceErrors = 'ignore-source-errors';
const format = 'format';
const conf = 'config';
const help = 'help';
const verbose = 'verbose';
const pubspecName = 'pubspec.yaml';
const configKey = 'ffigen';
const logAll = 'all';
const logFine = 'fine';
const logInfo = 'info';
const logWarning = 'warning';
const logSevere = 'severe';

Future<void> main(List<String> args) async {
  // Parses the cmd args. This will print usage and exit if --help was passed.
  final argResult = getArgResults(args);

  Logger.root.level = _parseLogLevel(argResult);

  // Create a config object.
  FfiGenerator generator;
  try {
    generator = getGenerator(
      argResult,
      await findPackageConfig(Directory.current),
    );
  } on FormatException {
    logger.severe('Please fix configuration errors and re-run the tool.');
    exit(1);
  }

  generator.generate(logger: logger);
}

FfiGenerator getGenerator(ArgResults result, PackageConfig? packageConfig) {
  logger.info('Running in ${Directory.current}');
  YamlConfig config;

  // Parse config from yaml.
  if (result.wasParsed(conf)) {
    config = getConfigFromCustomYaml(result[conf] as String, packageConfig);
  } else {
    config = getConfigFromPubspec(packageConfig);
  }

  // Add compiler options from command line.
  if (result.wasParsed(compilerOpts)) {
    logger.fine('Passed compiler opts - "${result[compilerOpts]}"');
    config.addCompilerOpts(result[compilerOpts] as String, highPriority: true);
  }

  if (result.wasParsed(ignoreSourceErrors)) {
    config.ignoreSourceErrors = true;
  }

  config.formatOutput = result[format] as bool;

  return config.configAdapter();
}

/// Extracts configuration from pubspec file.
YamlConfig getConfigFromPubspec(PackageConfig? packageConfig) {
  final pubspecFile = File(pubspecName);

  if (!pubspecFile.existsSync()) {
    logger.severe(
      'Error: $pubspecName not found, please run this tool from '
      'the root of your package.',
    );
    exit(1);
  }

  // Casting this because pubspec is expected to be a YamlMap.

  // Throws a [YamlException] if it's unable to parse the Yaml.
  final pubspecYaml =
      yaml.loadYaml(pubspecFile.readAsStringSync()) as yaml.YamlMap;
  final bindingsConfigMap = pubspecYaml[configKey] as yaml.YamlMap?;

  if (bindingsConfigMap == null) {
    logger.severe("Couldn't find an entry for '$configKey' in $pubspecName.");
    exit(1);
  }
  return YamlConfig.fromYaml(
    bindingsConfigMap,
    logger,
    filename: pubspecFile.path,
    packageConfig: packageConfig,
  );
}

/// Extracts configuration from a custom yaml file.
YamlConfig getConfigFromCustomYaml(
  String yamlPath,
  PackageConfig? packageConfig,
) {
  final yamlFile = File(yamlPath);

  if (!yamlFile.existsSync()) {
    logger.severe('Error: $yamlPath not found.');
    exit(1);
  }

  return YamlConfig.fromFile(yamlFile, logger, packageConfig: packageConfig);
}

/// Parses the cmd line arguments.
ArgResults getArgResults(List<String> args) {
  final parser = ArgParser(allowTrailingOptions: true);

  parser.addSeparator(
    'FFIGEN: Generate dart bindings from C header files\nUsage:',
  );
  parser.addOption(
    conf,
    help: 'Path to Yaml file containing configurations if not in pubspec.yaml',
  );
  parser.addOption(
    verbose,
    abbr: 'v',
    defaultsTo: logInfo,
    allowed: [logAll, logFine, logInfo, logWarning, logSevere],
  );
  parser.addFlag(help, abbr: 'h', help: 'Prints this usage', negatable: false);
  parser.addOption(
    compilerOpts,
    help: 'Compiler options for clang. (E.g --$compilerOpts "-I/headers -W")',
  );
  parser.addFlag(
    ignoreSourceErrors,
    help: 'Ignore any compiler warnings/errors in source header files',
    negatable: false,
  );
  parser.addFlag(
    format,
    help: 'Format the generated code.',
    defaultsTo: true,
    negatable: true,
  );

  ArgResults results;
  try {
    results = parser.parse(args);

    if (results.wasParsed(help)) {
      print(parser.usage);
      exit(0);
    }
  } catch (e) {
    print(e);
    print(parser.usage);
    exit(1);
  }

  return results;
}

Level _parseLogLevel(ArgResults result) {
  switch (result[verbose] as String?) {
    case logAll:
      // Logs everything, the entire AST touched by our parser.
      return Level.ALL;
    case logFine:
      // Logs AST parts relevant to user (i.e those included in filters).
      return Level.FINE;
    case logInfo:
      // Logs relevant info for general user (default).
      return Level.INFO;
    case logWarning:
      // Logs warnings for relevant stuff.
      return Level.WARNING;
    case logSevere:
      // Logs severe warnings and errors.
      return Level.SEVERE;
    default:
      return Level.INFO;
  }
}
