// Copyright (c) 2018, 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.

// This is a sample "tool" used to test external tool integration into dartdoc.
// It has no practical purpose other than that.

import 'dart:io';
import 'package:args/args.dart';

void main(List<String> argList) {
  final ArgParser argParser = ArgParser();
  argParser.addOption('file');
  argParser.addOption('special');
  argParser.addOption('source');
  argParser.addFlag('html', defaultsTo: false);
  argParser.addOption('package-name');
  argParser.addOption('package-path');
  argParser.addOption('library-name');
  argParser.addOption('element-name');
  final ArgResults args = argParser.parse(argList);
  // Normalize the filenames, since they include random
  // and system-specific components, but make sure they
  // match the patterns we expect.
  RegExp inputFileRegExp = new RegExp(
      r'(--file=)?(.*)([/\\]dartdoc_tools_)([^/\\]+)([/\\]input_)(\d+)');
  RegExp packagePathRegExp = new RegExp(
      r'(--package-path=)?(.+dartdoc.*[/\\]testing[/\\]test_package)');

  final Set<String> variableNames = new Set<String>.from([
    'INPUT',
    'SOURCE_COLUMN',
    'SOURCE_PATH',
    'PACKAGE_NAME',
    'PACKAGE_PATH',
    'LIBRARY_NAME',
    'ELEMENT_NAME',
    'INVOCATION_INDEX',
  ]);
  Map<String, String> env = <String, String>{}..addAll(Platform.environment);
  env.removeWhere((String key, String value) => !variableNames.contains(key));
  env.updateAll(
      (key, value) => inputFileRegExp.hasMatch(value) ? '<INPUT_FILE>' : value);
  env.updateAll((key, value) =>
      packagePathRegExp.hasMatch(value) ? '<PACKAGE_PATH>' : value);
  print('Env: ${env}');

  List<String> normalized = argList.map((String arg) {
    if (inputFileRegExp.hasMatch(arg)) {
      return '--file=<INPUT_FILE>';
    } else if (packagePathRegExp.hasMatch(arg)) {
      return '--package-path=<PACKAGE_PATH>';
    } else {
      return arg;
    }
  }).toList();
  RegExp snapshotCacheRegExp =
      new RegExp(r'.*[/\\]dartdoc_snapshot_cache_[^/\\]+[/\\]snapshot_0');
  RegExp snapshotFirstRegExp =
      new RegExp(r'.*[/\\]testing[/\\]test_package[/\\]bin[/\\]drill.dart$');
  if (snapshotCacheRegExp.hasMatch(Platform.script.path)) {
    print('Script location is in snapshot cache.');
  } else if (snapshotFirstRegExp.hasMatch(Platform.script.path)) {
    print('Script location is in dartdoc tree.');
  } else {
    print('Script location is not recognized: ${Platform.script.path}');
  }
  print('Args: $normalized');
  if (args['file'] != null) {
    File file = new File(args['file']);
    if (file.existsSync()) {
      List<String> lines = file.readAsLinesSync();
      for (String line in lines) {
        print('## `${line}`');
        if (args['html']) {
          print(
              '{@inject-html}<div class="title">Title</div>{@end-inject-html}');
        }
        print('\n$line Is not a [ToolUser].\n');
      }
    } else {
      exit(1);
    }
  }
  exit(0);
}
