// 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:convert';
import 'dart:io';

import 'package:flutter_devicelab/framework/framework.dart';
import 'package:flutter_devicelab/framework/task_result.dart';
import 'package:flutter_devicelab/framework/utils.dart';
import 'package:path/path.dart' as path;
import 'package:pub_semver/pub_semver.dart';
import 'package:pubspec_parse/pubspec_parse.dart';

// the numbers below are prime, so that the totals don't seem round. :-)
const double todoCost = 1009.0; // about two average SWE days, in dollars
const double ignoreCost = 2003.0; // four average SWE days, in dollars
const double pythonCost = 3001.0; // six average SWE days, in dollars
const double skipCost = 2473.0; // 20 hours: 5 to fix the issue we're ignoring, 15 to fix the bugs we missed because the test was off
const double ignoreForFileCost = 2477.0; // similar thinking as skipCost
const double asDynamicCost = 2011.0; // a few days to refactor the code.
const double deprecationCost = 233.0; // a few hours to remove the old code.
const double legacyDeprecationCost = 9973.0; // a couple of weeks.
const double packageNullSafetyMigrationCost = 2017.0; // a few days to migrate package.
const double fileNullSafetyMigrationCost = 257.0; // a few hours to migrate file.

final RegExp todoPattern = RegExp(r'(?://|#) *TODO');
final RegExp ignorePattern = RegExp(r'// *ignore:');
final RegExp ignoreForFilePattern = RegExp(r'// *ignore_for_file:');
final RegExp asDynamicPattern = RegExp(r'\bas dynamic\b');
final RegExp deprecationPattern = RegExp(r'^ *@[dD]eprecated');
const Pattern globalsPattern = 'globals.';
const String legacyDeprecationPattern = '// flutter_ignore: deprecation_syntax, https';
final RegExp dartVersionPattern = RegExp(r'// *@dart *= *(\d+).(\d+)');

final Version firstNullSafeDartVersion = Version(2, 12, 0);

Future<double> findCostsForFile(File file) async {
  if (path.extension(file.path) == '.py')
    return pythonCost;
  if (path.extension(file.path) != '.dart' &&
      path.extension(file.path) != '.yaml' &&
      path.extension(file.path) != '.sh')
    return 0.0;
  final bool isTest = file.path.endsWith('_test.dart');
  final bool isDart = file.path.endsWith('.dart');
  double total = 0.0;
  for (final String line in await file.readAsLines()) {
    if (line.contains(todoPattern))
      total += todoCost;
    if (line.contains(ignorePattern))
      total += ignoreCost;
    if (line.contains(ignoreForFilePattern))
      total += ignoreForFileCost;
    if (!isTest && line.contains(asDynamicPattern))
      total += asDynamicCost;
    if (line.contains(deprecationPattern))
      total += deprecationCost;
    if (line.contains(legacyDeprecationPattern))
      total += legacyDeprecationCost;
    if (isTest && line.contains('skip:') && !line.contains('[intended]'))
      total += skipCost;
    if (isDart && isOptingOutOfNullSafety(line))
      total += fileNullSafetyMigrationCost;
  }
  if (path.basename(file.path) == 'pubspec.yaml' && !packageIsNullSafe(file))
    total += packageNullSafetyMigrationCost;
  return total;
}

bool isOptingOutOfNullSafety(String line) {
  final RegExpMatch? match = dartVersionPattern.firstMatch(line);
  if (match == null) {
    return false;
  }
  assert(match.groupCount == 2);
  return Version(int.parse(match.group(1)!), int.parse(match.group(2)!), 0) < firstNullSafeDartVersion;
}

bool packageIsNullSafe(File file) {
  assert(path.basename(file.path) == 'pubspec.yaml');
  final Pubspec pubspec = Pubspec.parse(file.readAsStringSync());
  final VersionConstraint? constraint = pubspec.environment == null ? null : pubspec.environment!['sdk'];
  final bool hasConstraint = constraint != null && !constraint.isAny && !constraint.isEmpty;
  return hasConstraint &&
      constraint is VersionRange &&
      constraint.min != null &&
      Version(constraint.min!.major, constraint.min!.minor, 0) >= firstNullSafeDartVersion;
}

Future<int> findGlobalsForFile(File file) async {
  if (path.extension(file.path) != '.dart')
    return 0;
  int total = 0;
  for (final String line in await file.readAsLines()) {
    if (line.contains(globalsPattern))
      total += 1;
  }
  return total;
}

Future<double> findCostsForRepo() async {
  final Process git = await startProcess(
    'git',
    <String>['ls-files', '--full-name', flutterDirectory.path],
    workingDirectory: flutterDirectory.path,
  );
  double total = 0.0;
  await for (final String entry in git.stdout.transform<String>(utf8.decoder).transform<String>(const LineSplitter()))
    total += await findCostsForFile(File(path.join(flutterDirectory.path, entry)));
  final int gitExitCode = await git.exitCode;
  if (gitExitCode != 0)
    throw Exception('git exit with unexpected error code $gitExitCode');
  return total;
}

Future<int> findGlobalsForTool() async {
  final Process git = await startProcess(
    'git',
    <String>['ls-files', '--full-name', path.join(flutterDirectory.path, 'packages', 'flutter_tools')],
    workingDirectory: flutterDirectory.path,
  );
  int total = 0;
  await for (final String entry in git.stdout.transform<String>(utf8.decoder).transform<String>(const LineSplitter()))
    total += await findGlobalsForFile(File(path.join(flutterDirectory.path, entry)));
  final int gitExitCode = await git.exitCode;
  if (gitExitCode != 0)
    throw Exception('git exit with unexpected error code $gitExitCode');
  return total;
}

Future<int> countDependencies() async {
  final List<String> lines = (await evalFlutter(
    'update-packages',
    options: <String>['--transitive-closure'],
  )).split('\n');
  final int count = lines.where((String line) => line.contains('->')).length;
  if (count < 2) // we'll always have flutter and flutter_test, at least...
    throw Exception('"flutter update-packages --transitive-closure" returned bogus output:\n${lines.join("\n")}');
  return count;
}

Future<int> countConsumerDependencies() async {
  final List<String> lines = (await evalFlutter(
    'update-packages',
    options: <String>['--transitive-closure', '--consumer-only'],
  )).split('\n');
  final int count = lines.where((String line) => line.contains('->')).length;
  if (count < 2) // we'll always have flutter and flutter_test, at least...
    throw Exception('"flutter update-packages --transitive-closure" returned bogus output:\n${lines.join("\n")}');
  return count;
}

const String _kCostBenchmarkKey = 'technical_debt_in_dollars';
const String _kNumberOfDependenciesKey = 'dependencies_count';
const String _kNumberOfConsumerDependenciesKey = 'consumer_dependencies_count';
const String _kNumberOfFlutterToolGlobals = 'flutter_tool_globals_count';

Future<void> main() async {
  await task(() async {
    return TaskResult.success(
      <String, dynamic>{
        _kCostBenchmarkKey: await findCostsForRepo(),
        _kNumberOfDependenciesKey: await countDependencies(),
        _kNumberOfConsumerDependenciesKey: await countConsumerDependencies(),
        _kNumberOfFlutterToolGlobals: await findGlobalsForTool(),
      },
      benchmarkScoreKeys: <String>[
        _kCostBenchmarkKey,
        _kNumberOfDependenciesKey,
        _kNumberOfConsumerDependenciesKey,
        _kNumberOfFlutterToolGlobals,
      ],
    );
  });
}
