// Copyright 2013 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:convert' show utf8, LineSplitter;
import 'dart:io' as io;

import 'package:meta/meta.dart';
import 'package:path/path.dart' as path;
import 'package:process_runner/process_runner.dart';

/// The url prefix for issues that must be attached to the directive in files
/// that disables linting.
const String issueUrlPrefix = 'https://github.com/flutter/flutter/issues';

/// Lint actions to apply to a file.
enum LintAction {
  /// Run the linter over the file.
  lint,

  /// Ignore files under third_party/.
  skipThirdParty,

  /// Ignore due to a well-formed FLUTTER_NOLINT comment.
  skipNoLint,

  /// Fail due to a malformed FLUTTER_NOLINT comment.
  failMalformedNoLint,
}

/// A compilation command and methods to generate the lint command and job for
/// it.
class Command {
  /// Generate a [Command] from a [Map].
  Command.fromMap(Map<String, dynamic> map) :
    directory = io.Directory(map['directory'] as String).absolute,
    command = map['command'] as String {
    filePath = path.normalize(path.join(
      directory.path,
      map['file'] as String,
    ));
  }

  /// The working directory of the command.
  final io.Directory directory;

  /// The compilation command.
  final String command ;

  /// The file on which the command operates.
  late final String filePath;

  static final RegExp _pathRegex = RegExp(r'\S*clang/bin/clang');
  static final RegExp _argRegex = RegExp(r'-MF \S*');

  String? _tidyArgs;

  /// The command line arguments of the command.
  String get tidyArgs {
    return _tidyArgs ??= (() {
      String result = command;
      result = result.replaceAll(_pathRegex, '');
      result = result.replaceAll(_argRegex, '');
      return result;
    })();
  }

  String? _tidyPath;

  /// The command but with clang-tidy instead of clang.
  String get tidyPath {
    return _tidyPath ??= _pathRegex.stringMatch(command)?.replaceAll(
      'clang/bin/clang',
      'clang/bin/clang-tidy',
    ) ?? '';
  }

  /// Whether this command operates on any of the files in `queries`.
  bool containsAny(List<io.File> queries) {
    return queries.indexWhere(
      (io.File query) => path.equals(query.path, filePath),
    ) != -1;
  }

  static final RegExp _nolintRegex = RegExp(
    r'//\s*FLUTTER_NOLINT(: https://github.com/flutter/flutter/issues/\d+)?',
  );

  LintAction? _lintAction;

  /// The type of lint that is appropriate for this command.
  Future<LintAction> get lintAction async =>
    _lintAction ??= await getLintAction(filePath);

  /// Determine the lint action for the file at `path`.
  @visibleForTesting
  static Future<LintAction> getLintAction(String filePath) {
    if (path.split(filePath).contains('third_party')) {
      return Future<LintAction>.value(LintAction.skipThirdParty);
    }

    final io.File file = io.File(filePath);
    final Stream<String> lines = file.openRead()
      .transform(utf8.decoder)
      .transform(const LineSplitter());
    return lintActionFromContents(lines);
  }

  /// Determine the lint action for the file with contents `lines`.
  @visibleForTesting
  static Future<LintAction> lintActionFromContents(Stream<String> lines) async {
    // Check for FlUTTER_NOLINT at top of file.
    await for (final String line in lines) {
      final RegExpMatch? match = _nolintRegex.firstMatch(line);
      if (match != null) {
        return match.group(1) != null
          ? LintAction.skipNoLint
          : LintAction.failMalformedNoLint;
      } else if (line.isNotEmpty && line[0] != '\n' && line[0] != '/') {
        // Quick out once we find a line that isn't empty or a comment.  The
        // FLUTTER_NOLINT must show up before the first real code.
        return LintAction.lint;
      }
    }
    return LintAction.lint;
  }

  /// The job for the process runner for the lint needed for this command.
  WorkerJob createLintJob(String checks) {
    final List<String> args = <String>[filePath, checks, '--'];
    args.addAll(tidyArgs.split(' '));
    return WorkerJob(
      <String>[tidyPath, ...args],
      workingDirectory: directory,
      name: 'clang-tidy on $filePath',
    );
  }
}
