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

library dartdoc.bin;

import 'dart:io';

import 'package:args/args.dart';
import 'package:cli_util/cli_util.dart' as cli_util;
import 'package:dartdoc/dartdoc.dart';
import 'package:dartdoc/src/config.dart';
import 'package:dartdoc/src/package_meta.dart';
import 'package:path/path.dart' as path;
import 'package:stack_trace/stack_trace.dart';
import 'package:analyzer/src/generated/sdk.dart';
import 'package:analyzer/src/generated/sdk_io.dart';
import 'package:analyzer/src/generated/java_io.dart';

/// Analyzes Dart files and generates a representation of included libraries,
/// classes, and members. Uses the current directory to look for libraries.
main(List<String> arguments) async {
  var parser = _createArgsParser();
  ArgResults args;
  try {
    args = parser.parse(arguments);
  } on FormatException catch (e) {
    print(e.message);
    print('');
    // http://linux.die.net/include/sysexits.h
    // #define EX_USAGE	64	/* command line usage error */
    _printUsageAndExit(parser, exitCode: 64);
  }

  if (args['help']) {
    _printHelp(parser);
  }

  if (args['version']) {
    print('$name version: $version');
    exit(0);
  }

  Directory sdkDir = cli_util.getSdkDir(arguments);
  if (sdkDir == null) {
    print("Error: unable to locate the Dart SDK. Please use the --dart-sdk "
        "command line option or set the DART_SDK environment variable.");
    exit(1);
  }

  bool sdkDocs = false;
  if (args['sdk-docs']) {
    sdkDocs = true;
  }

  if (args['show-progress']) {
    _showProgress = true;
  }

  var readme = args['sdk-readme'];
  if (readme != null && !(new File(readme).existsSync())) {
    print("Error: unable to locate the SDK description file at $readme.");
    exit(1);
  }

  Directory inputDir = new Directory(args['input']);
  if (!inputDir.existsSync()) {
    print("Error: unable to locate the input directory at ${inputDir.path}.");
    exit(1);
  }

  List<String> excludeLibraries = args['exclude'];
  List<String> includeLibraries = args['include'];
  List<String> includeExternals = args['include-external'];

  String url = args['hosted-url'];
  List<String> footerFilePaths = args['footer'].map(_resolveTildePath).toList();
  for (String footerFilePath in footerFilePaths) {
    if (!new File(footerFilePath).existsSync()) {
      print("Error: unable to locate footer file: ${footerFilePath}.");
      exit(1);
    }
  }
  List<String> headerFilePaths = args['header'].map(_resolveTildePath).toList();
  for (String headerFilePath in footerFilePaths) {
    if (!new File(headerFilePath).existsSync()) {
      print("Error: unable to locate header file: ${headerFilePath}.");
      exit(1);
    }
  }

  Directory outputDir =
      new Directory(path.join(Directory.current.path, defaultOutDir));
  if (args['output'] != null) {
    outputDir = new Directory(_resolveTildePath(args['output']));
  }

  if (args.rest.isNotEmpty) {
    var unknownArgs = args.rest.join(' ');
    print('Error: detected unknown command-line argument(s): $unknownArgs');
    _printUsageAndExit(parser, exitCode: 1);
  }

  PackageMeta packageMeta = sdkDocs
      ? new PackageMeta.fromSdk(sdkDir, sdkReadmePath: readme)
      : new PackageMeta.fromDir(inputDir);

  if (!packageMeta.isValid) {
    print('Unable to generate documentation.');
    packageMeta.getInvalidReasons().map((r) => '* $r').forEach(print);
    exit(1);
  }

  print("Generating documentation for '${packageMeta}' into "
      "${outputDir.absolute.path}${Platform.pathSeparator}");
  print('');

  var generators = await initGenerators(
      url, headerFilePaths, footerFilePaths, args['rel-canonical-prefix'],
      faviconPath: args['favicon'], useCategories: args['use-categories']);

  for (var generator in generators) {
    generator.onFileCreated.listen(_onProgress);
  }

  var addCrossdart = args['add-crossdart'] as bool;
  var includeSource = args['include-source'] as bool;

  DartSdk sdk = new DirectoryBasedDartSdk(new JavaFile(sdkDir.path));

  initializeConfig(
      addCrossdart: addCrossdart,
      includeSource: includeSource,
      inputDir: inputDir,
      sdkVersion: sdk.sdkVersion);

  var dartdoc = new DartDoc(inputDir, excludeLibraries, sdkDir, generators,
      outputDir, packageMeta, includeLibraries,
      includeExternals: includeExternals);

  Chain.capture(() async {
    DartDocResults results = await dartdoc.generateDocs();
    print('\nSuccess! Docs generated into ${results.outDir.absolute.path}');
  }, onError: (e, Chain chain) {
    if (e is DartDocFailure) {
      stderr.writeln('Generation failed: ${e}.');
      exit(1);
    } else {
      stderr.writeln('Generation failed: ${e}\n${chain.terse}');
      exit(255);
    }
  });
}

bool _showProgress = false;

ArgParser _createArgsParser() {
  var parser = new ArgParser();
  parser.addFlag('help',
      abbr: 'h', negatable: false, help: 'Show command help.');
  parser.addFlag('version',
      help: 'Display the version for $name.', negatable: false);
  parser.addFlag('add-crossdart',
      help: 'Add Crossdart links to the source code pieces.',
      negatable: false,
      defaultsTo: false);
  parser.addOption('dart-sdk',
      help:
          "Location of the Dart SDK. Use if SDK isn't automatically located.");
  parser.addFlag('sdk-docs',
      help: 'Generate ONLY the docs for the Dart SDK.', negatable: false);
  parser.addFlag('show-progress',
      help: 'Display progress indications to console stdout', negatable: false);
  parser.addOption('sdk-readme',
      help:
          'Path to the SDK description file. Use if generating Dart SDK docs.');
  parser.addOption('input',
      help: 'Path to source directory', defaultsTo: Directory.current.path);
  parser.addOption('output',
      help: 'Path to output directory.', defaultsTo: defaultOutDir);
  parser.addOption('header',
      allowMultiple: true, help: 'path to file containing HTML text.');
  parser.addOption('footer',
      allowMultiple: true, help: 'path to file containing HTML text.');
  parser.addOption('exclude',
      allowMultiple: true, help: 'library names to ignore');
  parser.addOption('include',
      allowMultiple: true, help: 'library names to generate docs for');
  parser.addOption('include-external',
      allowMultiple: true, help: 'additional (external) libraries to include');
  parser.addOption('hosted-url',
      help:
          'URL where the docs will be hosted (used to generate the sitemap).');
  parser.addOption('rel-canonical-prefix',
      help:
          'If provided, add a rel="canonical" prefixed with provided value. \n'
          'Consider using if building many versions of the docs for public SEO. '
          'Learn more at https://goo.gl/gktN6F.');
  parser.addFlag('include-source',
      help: 'Show source code blocks', negatable: true, defaultsTo: true);
  parser.addOption('favicon',
      help: 'A path to a favicon for the generated docs');
  parser.addFlag('use-categories',
      help: 'Group libraries from the same package into categories',
      negatable: false,
      defaultsTo: false);
  return parser;
}

void _onProgress(File file) {
  if (_showProgress) stdout.write('.');
}

/// Print help if we are passed the help option.
void _printHelp(ArgParser parser, {int exitCode: 0}) {
  print('Generate HTML documentation for Dart libraries.\n');
  _printUsageAndExit(parser, exitCode: exitCode);
}

void _printUsageAndExit(ArgParser parser, {int exitCode: 0}) {
  print('Usage: dartdoc [OPTIONS]\n');
  print(parser.usage);
  exit(exitCode);
}

String _resolveTildePath(String originalPath) {
  if (originalPath == null || !originalPath.startsWith('~/')) {
    return originalPath;
  }

  String homeDir;

  if (Platform.isWindows) {
    homeDir = path.absolute(Platform.environment['USERPROFILE']);
  } else {
    homeDir = path.absolute(Platform.environment['HOME']);
  }

  return path.join(homeDir, originalPath.substring(2));
}
