// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import 'dart:io';

import 'package:args/args.dart';
import 'package:path/path.dart' as path;

import 'configuration.dart';
import 'snippets.dart';

const String _kSerialOption = 'serial';
const String _kElementOption = 'element';
const String _kHelpOption = 'help';
const String _kInputOption = 'input';
const String _kLibraryOption = 'library';
const String _kOutputOption = 'output';
const String _kPackageOption = 'package';
const String _kTemplateOption = 'template';
const String _kTypeOption = 'type';
const String _kShowDartPad = 'dartpad';

String getChannelName() {
  final RegExp gitBranchRegexp = RegExp(r'^## (.*)');
  final ProcessResult gitResult = Process.runSync('git', <String>['status', '-b', '--porcelain']);
  if (gitResult.exitCode != 0)
    throw 'git status exit with non-zero exit code: ${gitResult.exitCode}';
  final Match gitBranchMatch = gitBranchRegexp.firstMatch(
      (gitResult.stdout as String).trim().split('\n').first);
  return gitBranchMatch == null ? '<unknown>' : gitBranchMatch.group(1).split('...').first;
}

/// Generates snippet dartdoc output for a given input, and creates any sample
/// applications needed by the snippet.
void main(List<String> argList) {
  final Map<String, String> environment = Platform.environment;
  final ArgParser parser = ArgParser();
  final List<String> snippetTypes =
      SnippetType.values.map<String>((SnippetType type) => getEnumName(type)).toList();
  parser.addOption(
    _kTypeOption,
    defaultsTo: getEnumName(SnippetType.sample),
    allowed: snippetTypes,
    allowedHelp: <String, String>{
      getEnumName(SnippetType.sample):
          'Produce a code sample application complete with embedding the sample in an '
          'application template.',
      getEnumName(SnippetType.snippet):
          'Produce a nicely formatted piece of sample code. Does not embed the '
          'sample into an application template.',
    },
    help: 'The type of snippet to produce.',
  );
  parser.addOption(
    _kTemplateOption,
    defaultsTo: null,
    help: 'The name of the template to inject the code into.',
  );
  parser.addOption(
    _kOutputOption,
    defaultsTo: null,
    help: 'The output path for the generated sample application. Overrides '
        'the naming generated by the --package/--library/--element arguments. '
        'Metadata will be written alongside in a .json file. '
        'The basename of this argument is used as the ID',
  );
  parser.addOption(
    _kInputOption,
    defaultsTo: environment['INPUT'],
    help: 'The input file containing the sample code to inject.',
  );
  parser.addOption(
    _kPackageOption,
    defaultsTo: environment['PACKAGE_NAME'],
    help: 'The name of the package that this sample belongs to.',
  );
  parser.addOption(
    _kLibraryOption,
    defaultsTo: environment['LIBRARY_NAME'],
    help: 'The name of the library that this sample belongs to.',
  );
  parser.addOption(
    _kElementOption,
    defaultsTo: environment['ELEMENT_NAME'],
    help: 'The name of the element that this sample belongs to.',
  );
  parser.addOption(
    _kSerialOption,
    defaultsTo: environment['INVOCATION_INDEX'],
    help: 'A unique serial number for this snippet tool invocation.',
  );
  parser.addFlag(
    _kHelpOption,
    defaultsTo: false,
    negatable: false,
    help: 'Prints help documentation for this command',
  );
  parser.addFlag(
    _kShowDartPad,
    defaultsTo: false,
    negatable: false,
    help: "Indicates whether DartPad should be included in the sample's "
        'final HTML output. This flag only applies when the type parameter is '
        '"sample".',
  );

  final ArgResults args = parser.parse(argList);

  if (args[_kHelpOption] as bool) {
    stderr.writeln(parser.usage);
    exit(0);
  }

  final SnippetType snippetType = SnippetType.values
      .firstWhere((SnippetType type) => getEnumName(type) == args[_kTypeOption], orElse: () => null);
  assert(snippetType != null, "Unable to find '${args[_kTypeOption]}' in SnippetType enum.");

  if (args[_kShowDartPad] == true && snippetType != SnippetType.sample) {
    errorExit('${args[_kTypeOption]} was selected, but the --dartpad flag is only valid '
      'for application sample code.');
  }

  if (args[_kInputOption] == null) {
    stderr.writeln(parser.usage);
    errorExit('The --$_kInputOption option must be specified, either on the command '
        'line, or in the INPUT environment variable.');
  }

  final File input = File(args['input'] as String);
  if (!input.existsSync()) {
    errorExit('The input file ${input.path} does not exist.');
  }

  String template;
  if (snippetType == SnippetType.sample) {
    final String templateArg = args[_kTemplateOption] as String;
    if (templateArg == null || templateArg.isEmpty) {
      stderr.writeln(parser.usage);
      errorExit('The --$_kTemplateOption option must be specified on the command '
          'line for application samples.');
    }
    template = templateArg.replaceAll(RegExp(r'.tmpl$'), '');
  }

  String emptyToNull(String value) => value?.isEmpty ?? true ? null : value;
  final String packageName = emptyToNull(args[_kPackageOption] as String);
  final String libraryName = emptyToNull(args[_kLibraryOption] as String);
  final String elementName = emptyToNull(args[_kElementOption] as String);
  final String serial = emptyToNull(args[_kSerialOption] as String);
  final List<String> id = <String>[];
  if (args[_kOutputOption] != null) {
    id.add(path.basename(path.basenameWithoutExtension(args[_kOutputOption] as String)));
  } else {
    if (packageName != null && packageName != 'flutter') {
      id.add(packageName);
    }
    if (libraryName != null) {
      id.add(libraryName);
    }
    if (elementName != null) {
      id.add(elementName);
    }
    if (serial != null) {
      id.add(serial);
    }
    if (id.isEmpty) {
      errorExit('Unable to determine ID. At least one of --$_kPackageOption, '
          '--$_kLibraryOption, --$_kElementOption, -$_kSerialOption, or the environment variables '
          'PACKAGE_NAME, LIBRARY_NAME, ELEMENT_NAME, or INVOCATION_INDEX must be non-empty.');
    }
  }

  final SnippetGenerator generator = SnippetGenerator();
  stdout.write(generator.generate(
    input,
    snippetType,
    showDartPad: args[_kShowDartPad] as bool,
    template: template,
    output: args[_kOutputOption] != null ? File(args[_kOutputOption] as String) : null,
    metadata: <String, Object>{
      'sourcePath': environment['SOURCE_PATH'],
      'sourceLine': environment['SOURCE_LINE'] != null
          ? int.tryParse(environment['SOURCE_LINE'])
          : null,
      'id': id.join('.'),
      'channel': getChannelName(),
      'serial': serial,
      'package': packageName,
      'library': libraryName,
      'element': elementName,
    },
  ));

  exit(0);
}
