// 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' hide Platform;

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

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) {
  const Platform platform = LocalPlatform();
  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);
}
