// 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;
}
