// 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' show ProcessResult, exitCode, stderr;

import 'package:args/args.dart';
import 'package:file/file.dart';
import 'package:file/local.dart';
import 'package:path/path.dart' as path;
import 'package:platform/platform.dart';
import 'package:process/process.dart';
import 'package:snippets/snippets.dart';

const String _kElementOption = 'element';
const String _kHelpOption = 'help';
const String _kInputOption = 'input';
const String _kLibraryOption = 'library';
const String _kOutputDirectoryOption = 'output-directory';
const String _kOutputOption = 'output';
const String _kPackageOption = 'package';
const String _kSerialOption = 'serial';
const String _kTypeOption = 'type';

class GitStatusFailed implements Exception {
  GitStatusFailed(this.gitResult);

  final ProcessResult gitResult;

  @override
  String toString() {
    return 'git status exited with a non-zero exit code: '
        '${gitResult.exitCode}:\n${gitResult.stderr}\n${gitResult.stdout}';
  }
}

/// A singleton filesystem that can be set by tests to a memory filesystem.
FileSystem filesystem = const LocalFileSystem();

/// A singleton snippet generator that can be set by tests to a mock, so that
/// we can test the command line parsing.
SnippetGenerator snippetGenerator = SnippetGenerator();

/// A singleton platform that can be set by tests for use in testing command line
/// parsing.
Platform platform = const LocalPlatform();

/// A singleton process manager that can be set by tests for use in testing.
ProcessManager processManager = const LocalProcessManager();

/// Get the name of the channel these docs are from.
///
/// First check env variable LUCI_BRANCH, then refer to the currently
/// checked out git branch.
String getChannelName({
  Platform platform = const LocalPlatform(),
  ProcessManager processManager = const LocalProcessManager(),
}) {
  switch (platform.environment['LUCI_BRANCH']?.trim()) {
    // Backward compatibility: Still support running on "master", but pretend it is "main".
    case 'master' || 'main':
      return 'main';
    case 'stable':
      return 'stable';
  }

  final RegExp gitBranchRegexp = RegExp(r'^## (?<branch>.*)');
  final ProcessResult gitResult = processManager.runSync(
    <String>['git', 'status', '-b', '--porcelain'],
    // Use the FLUTTER_ROOT, if defined.
    workingDirectory:
        platform.environment['FLUTTER_ROOT']?.trim() ?? filesystem.currentDirectory.path,
    // Adding extra debugging output to help debug why git status inexplicably fails
    // (random non-zero error code) about 2% of the time.
    environment: <String, String>{'GIT_TRACE': '2', 'GIT_TRACE_SETUP': '2'},
  );
  if (gitResult.exitCode != 0) {
    throw GitStatusFailed(gitResult);
  }

  final RegExpMatch? gitBranchMatch = gitBranchRegexp.firstMatch(
    (gitResult.stdout as String).trim().split('\n').first,
  );
  return gitBranchMatch == null
      ? '<unknown>'
      : gitBranchMatch.namedGroup('branch')!.split('...').first;
}

const List<String> sampleTypes = <String>['snippet', 'sample', 'dartpad'];

// This is a hack to workaround the fact that git status inexplicably fails
// (with random non-zero error code) about 2% of the time.
String getChannelNameWithRetries({
  Platform platform = const LocalPlatform(),
  ProcessManager processManager = const LocalProcessManager(),
}) {
  int retryCount = 0;

  while (retryCount < 2) {
    try {
      return getChannelName(platform: platform, processManager: processManager);
    } on GitStatusFailed catch (e) {
      retryCount += 1;
      stderr.write('git status failed, retrying ($retryCount)\nError report:\n$e');
    }
  }

  return getChannelName(platform: platform, processManager: processManager);
}

/// 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();

  parser.addOption(
    _kTypeOption,
    defaultsTo: 'dartpad',
    allowed: sampleTypes,
    allowedHelp: <String, String>{
      'dartpad': 'Produce a code sample application for using in Dartpad.',
      'sample': 'Produce a code sample application.',
      'snippet': 'Produce a nicely formatted piece of sample code.',
    },
    help: 'The type of snippet to produce.',
  );
  parser.addOption(
    _kOutputOption,
    help:
        'The output name for the generated sample application. Overrides '
        'the naming generated by the --$_kPackageOption/--$_kLibraryOption/--$_kElementOption '
        'arguments. Metadata will be written alongside in a .json file. '
        'The basename of this argument is used as the ID. If this is a '
        'relative path, will be placed under the --$_kOutputDirectoryOption location.',
  );
  parser.addOption(
    _kOutputDirectoryOption,
    defaultsTo: '.',
    help: 'The output path for the generated sample application.',
  );
  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,
    negatable: false,
    help: 'Prints help documentation for this command',
  );

  final ArgResults args = parser.parse(argList);

  if (args[_kHelpOption]! as bool) {
    stderr.writeln(parser.usage);
    exitCode = 0;
    return;
  }

  final String sampleType = args[_kTypeOption]! as String;

  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.',
    );
    return;
  }

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

  final String packageName = args[_kPackageOption] as String? ?? '';
  final String libraryName = args[_kLibraryOption] as String? ?? '';
  final String elementName = args[_kElementOption] as String? ?? '';
  final String serial = args[_kSerialOption] as String? ?? '';
  late String id;
  File? output;
  final Directory outputDirectory =
      filesystem.directory(args[_kOutputDirectoryOption]! as String).absolute;

  if (args[_kOutputOption] != null) {
    id = path.basenameWithoutExtension(args[_kOutputOption]! as String);
    final File outputPath = filesystem.file(args[_kOutputOption]! as String);
    if (outputPath.isAbsolute) {
      output = outputPath;
    } else {
      output = filesystem.file(path.join(outputDirectory.path, outputPath.path));
    }
  } else {
    final List<String> idParts = <String>[];
    if (packageName.isNotEmpty && packageName != 'flutter') {
      idParts.add(packageName.replaceAll(RegExp(r'\W'), '_').toLowerCase());
    }
    if (libraryName.isNotEmpty) {
      idParts.add(libraryName.replaceAll(RegExp(r'\W'), '_').toLowerCase());
    }
    if (elementName.isNotEmpty) {
      idParts.add(elementName);
    }
    if (serial.isNotEmpty) {
      idParts.add(serial);
    }
    if (idParts.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.',
      );
      return;
    }
    id = idParts.join('.');
    output = outputDirectory.childFile('$id.dart');
  }
  output.parent.createSync(recursive: true);

  final int? sourceLine =
      environment['SOURCE_LINE'] != null ? int.tryParse(environment['SOURCE_LINE']!) : null;
  final String sourcePath = environment['SOURCE_PATH'] ?? 'unknown.dart';
  final SnippetDartdocParser sampleParser = SnippetDartdocParser(filesystem);
  final SourceElement element = sampleParser.parseFromDartdocToolFile(
    input,
    startLine: sourceLine,
    element: elementName,
    sourceFile: filesystem.file(sourcePath),
    type: sampleType,
  );
  final Map<String, Object?> metadata = <String, Object?>{
    'channel': getChannelNameWithRetries(platform: platform, processManager: processManager),
    'serial': serial,
    'id': id,
    'package': packageName,
    'library': libraryName,
    'element': elementName,
  };

  for (final CodeSample sample in element.samples) {
    sample.metadata.addAll(metadata);
    snippetGenerator.generateCode(sample, output: output);
    print(snippetGenerator.generateHtml(sample));
  }

  exitCode = 0;
}
