// 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.

import 'dart:async';
import 'dart:convert';
import 'dart:io' show Platform, exitCode, stderr;

import 'package:analyzer/file_system/file_system.dart';
import 'package:dartdoc/src/dartdoc_options.dart';
import 'package:dartdoc/src/failure.dart';
import 'package:dartdoc/src/generator/empty_generator.dart';
import 'package:dartdoc/src/generator/generator.dart';
import 'package:dartdoc/src/generator/html_generator.dart';
import 'package:dartdoc/src/logging.dart';
import 'package:dartdoc/src/model/model.dart';
import 'package:dartdoc/src/package_meta.dart';
import 'package:dartdoc/src/runtime_stats.dart';
import 'package:dartdoc/src/utils.dart';
import 'package:dartdoc/src/validator.dart';
import 'package:dartdoc/src/version.dart';
import 'package:dartdoc/src/warnings.dart';
import 'package:meta/meta.dart';
import 'package:path/path.dart' as path;

const String programName = 'dartdoc';
// Update when pubspec version changes by running `pub run build_runner build`
const String dartdocVersion = packageVersion;

class DartdocFileWriter implements FileWriter {
  final String _outputDir;
  @override
  final ResourceProvider resourceProvider;
  final Map<String, Warnable?> _fileElementMap = {};
  @override
  final Set<String> writtenFiles = {};

  final int _maxFileCount;
  final int _maxTotalSize;

  int _fileCount = 0;
  int _totalSize = 0;

  DartdocFileWriter(
    this._outputDir,
    this.resourceProvider, {
    int maxFileCount = 0,
    int maxTotalSize = 0,
  })  : _maxFileCount = maxFileCount,
        _maxTotalSize = maxTotalSize;

  void _validateMaxWriteStats(String filePath, int size) {
    _fileCount++;
    _totalSize += size;
    if (_maxFileCount > 0 && _maxFileCount < _fileCount) {
      throw DartdocFailure(
          'Maximum file count reached: $_maxFileCount ($filePath)');
    }
    if (_maxTotalSize > 0 && _maxTotalSize < _totalSize) {
      throw DartdocFailure(
          'Maximum total size reached: $_maxTotalSize bytes ($filePath)');
    }
  }

  @override
  void writeBytes(
    String filePath,
    List<int> content, {
    bool allowOverwrite = false,
  }) {
    _validateMaxWriteStats(filePath, content.length);
    // Replace '/' separators with proper separators for the platform.
    var outFile = path.joinAll(filePath.split('/'));

    if (!allowOverwrite) {
      _warnAboutOverwrite(outFile, null);
    }
    _fileElementMap[outFile] = null;

    var file = _getFile(outFile);
    file.writeAsBytesSync(content);
    writtenFiles.add(outFile);
    logProgress(outFile);
  }

  @override
  void write(String filePath, String content, {Warnable? element}) {
    final bytes = utf8.encode(content);
    _validateMaxWriteStats(filePath, bytes.length);

    // Replace '/' separators with proper separators for the platform.
    var outFile = path.joinAll(filePath.split('/'));

    _warnAboutOverwrite(outFile, element);
    _fileElementMap[outFile] = element;

    var file = _getFile(outFile);
    file.writeAsBytesSync(bytes);
    writtenFiles.add(outFile);
    logProgress(outFile);
  }

  void _warnAboutOverwrite(String outFile, Warnable? element) {
    if (_fileElementMap.containsKey(outFile)) {
      assert(element != null,
          'Attempted overwrite of $outFile without corresponding element');
      var originalElement = _fileElementMap[outFile];
      var referredFrom =
          originalElement == null ? const <Warnable>[] : [originalElement];
      element?.warn(PackageWarning.duplicateFile,
          message: outFile, referredFrom: referredFrom);
    }
  }

  /// Returns the file at [outFile] relative to [_outputDir], creating the
  /// parent directory if necessary.
  File _getFile(String outFile) {
    var file = resourceProvider
        .getFile(resourceProvider.pathContext.join(_outputDir, outFile));
    var parent = file.parent;
    if (!parent.exists) {
      parent.create();
    }
    return file;
  }
}

/// Generates Dart documentation for all public Dart libraries in the given
/// directory.
class Dartdoc {
  Generator _generator;
  final PackageBuilder packageBuilder;
  final DartdocOptionContext config;
  final Folder _outputDir;

  // Fires when the self checks make progress.
  final StreamController<String> _onCheckProgress =
      StreamController(sync: true);

  Dartdoc._(this.config, this._outputDir, this._generator, this.packageBuilder);

  Generator get generator => _generator;

  @visibleForTesting
  set generator(Generator newGenerator) => _generator = newGenerator;

  /// Factory method that builds Dartdoc with an empty generator.
  static Dartdoc withEmptyGenerator(
    DartdocOptionContext config,
    PackageBuilder packageBuilder,
  ) {
    return Dartdoc._(
      config,
      config.resourceProvider.getFolder('UNUSED'),
      initEmptyGenerator(),
      packageBuilder,
    );
  }

  /// Asynchronous factory method that builds Dartdoc with a generator
  /// determined by the given context.
  static Future<Dartdoc> fromContext(
    DartdocGeneratorOptionContext context,
    PackageBuilder packageBuilder,
  ) async {
    var resourceProvider = context.resourceProvider;
    var outputPath = resourceProvider.pathContext.absolute(context.output);
    var outputDir = resourceProvider.getFolder(outputPath)..create();
    var writer = DartdocFileWriter(
      outputPath,
      resourceProvider,
      maxFileCount: context.maxFileCount,
      maxTotalSize: context.maxTotalSize,
    );
    return Dartdoc._(
      context,
      outputDir,
      await initHtmlGenerator(context, writer: writer),
      packageBuilder,
    );
  }

  Stream<String> get onCheckProgress => _onCheckProgress.stream;

  @visibleForTesting
  Future<DartdocResults> generateDocsBase() async {
    var stopwatch = Stopwatch()..start();
    runtimeStats.startPerfTask('buildPackageGraph');
    var packageGraph = await packageBuilder.buildPackageGraph();
    runtimeStats.endPerfTask();
    if (packageBuilder.includeExternalsWasSpecified) {
      packageGraph.defaultPackage.warn(
        PackageWarning.deprecated,
        message:
            "The '--include-externals' option is deprecated, and will soon be "
            'removed.',
      );
    }
    var libs = packageGraph.libraryCount;
    logInfo("Initialized dartdoc with $libs librar${libs == 1 ? 'y' : 'ies'}");

    runtimeStats.startPerfTask('generator.generate');
    await generator.generate(packageGraph);
    runtimeStats.endPerfTask();

    var writtenFiles = generator.writtenFiles;
    if (config.validateLinks && writtenFiles.isNotEmpty) {
      runtimeStats.startPerfTask('validateLinks');
      Validator(packageGraph, config, _outputDir.path, writtenFiles,
              _onCheckProgress)
          .validateLinks();
      runtimeStats.endPerfTask();
    }

    var warnings = packageGraph.packageWarningCounter.warningCount;
    var errors = packageGraph.packageWarningCounter.errorCount;
    logWarning("Found $warnings ${pluralize('warning', warnings)} "
        "and $errors ${pluralize('error', errors)}.");

    var seconds = stopwatch.elapsedMilliseconds / 1000.0;
    libs = packageGraph.localPublicLibraries.length;
    logInfo("Documented $libs public librar${libs == 1 ? 'y' : 'ies'} "
        'in ${seconds.toStringAsFixed(1)} seconds');

    if (config.showStats) {
      logInfo(runtimeStats.buildReport());
    }
    return DartdocResults(config.topLevelPackageMeta, packageGraph, _outputDir);
  }

  /// Generates Dartdoc documentation.
  ///
  /// [DartdocResults] is returned if dartdoc succeeds. [DartdocFailure] is
  /// thrown if dartdoc fails in an expected way, for example if there is an
  /// analysis error in the code.
  Future<DartdocResults> generateDocs() async {
    DartdocResults? dartdocResults;
    try {
      logInfo('Documenting ${config.topLevelPackageMeta}...');

      dartdocResults = await generateDocsBase();
      if (dartdocResults.packageGraph.localPublicLibraries.isEmpty) {
        logWarning('dartdoc could not find any libraries to document');
      }

      final errorCount =
          dartdocResults.packageGraph.packageWarningCounter.errorCount;
      if (errorCount > 0) {
        throw DartdocFailure('encountered $errorCount errors');
      }
      var outDirPath = config.resourceProvider.pathContext
          .absolute(dartdocResults.outDir.path);
      logInfo('Success! Docs generated into $outDirPath');
      return dartdocResults;
    } finally {
      dartdocResults?.packageGraph.dispose();
    }
  }

  /// Runs [generateDocs] function and properly handles the errors.
  void executeGuarded() {
    onCheckProgress.listen(logProgress);
    // This function should *never* `await runZonedGuarded` because the errors
    // thrown in [generateDocs] are uncaught. We want this because uncaught
    // errors cause IDE debugger to automatically stop at the exception.
    //
    // If you await the zone, the code that comes after the await is not
    // executed if the zone dies due to an uncaught error. To avoid this,
    // confusion, never `await runZonedGuarded`.
    runZonedGuarded(
      () async {
        runtimeStats.startPerfTask('generateDocs');
        await generateDocs();
        runtimeStats.endPerfTask();
      },
      (e, stackTrace) {
        stderr.writeln('\n$_dartdocFailedMessage: $e\n$stackTrace');
        exitCode = e is DartdocFailure ? 1 : 255;
      },
      zoneSpecification: ZoneSpecification(
        print: (_, __, ___, String line) => logInfo(line),
      ),
    );
  }
}

/// The results of a [Dartdoc.generateDocs] call.
class DartdocResults {
  final PackageMeta packageMeta;
  final PackageGraph packageGraph;
  final Folder outDir;

  DartdocResults(this.packageMeta, this.packageGraph, this.outDir);
}

String get _dartdocFailedMessage =>
    'dartdoc $packageVersion (${Platform.script.path}) failed';
