// 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:'))
      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,
      ],
    );
  });
}
