// Copyright (c) 2019, 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:io';

import 'package:analyzer/src/lint/registry.dart';
import 'package:github/github.dart';
import 'package:http/http.dart' as http;
import 'package:linter/src/analyzer.dart';
import 'package:linter/src/rules.dart';
import 'package:linter/src/util/score_utils.dart' as score_utils;
import 'package:pub_semver/pub_semver.dart';
import 'package:yaml/yaml.dart';

const _allPathSuffix = '/example/all.yaml';
final _effectiveDartOptionsRootUrl = Uri.https(
    'raw.githubusercontent.com', '/tenhobi/effective_dart/master/lib/');
final _effectiveDartOptionsUrl =
    _effectiveDartOptionsRootUrl.resolve('analysis_options.yaml');

final _flutterOptionsUrl = Uri.https('raw.githubusercontent.com',
    '/flutter/flutter/master/packages/flutter/lib/analysis_options_user.yaml');
final _flutterRepoOptionsUrl = Uri.https('raw.githubusercontent.com',
    '/flutter/flutter/master/analysis_options.yaml');
final _repoPathPrefix =
    Uri.https('raw.githubusercontent.com', '/dart-lang/linter/');
final _rulePathPrefix =
    Uri.https('raw.githubusercontent.com', '/dart-lang/linter/');
final _stagehandOptionsUrl = Uri.https('raw.githubusercontent.com',
    '/dart-lang/stagehand/master/templates/analysis_options.yaml');

/// We don't care about SDKs previous to this bottom.
final Version bottomDartSdk = Version(2, 0, 0);

Map<String, String> _dartSdkToLinterMap = <String, String>{};

List<String> _effectiveDartRules;
List<String> _flutterRepoRules;
List<String> _flutterRules;
int _latestMinor;

Iterable<LintRule> _registeredLints;

List<String> _sdkTags;

Map<String, List<String>> _sinceMap = <String, List<String>>{};

List<String> _stagehandRules;

Future<List<String>> get effectiveDartRules async =>
    _effectiveDartRules ??= await _fetchEffectiveDartRules();

Future<List<String>> get flutterRepoRules async =>
    _flutterRepoRules ??= await score_utils.fetchRules(_flutterRepoOptionsUrl);

Future<List<String>> get flutterRules async =>
    _flutterRules ??= await score_utils.fetchRules(_flutterOptionsUrl);

Future<int> get latestMinor async =>
    _latestMinor ??= await _readLatestMinorVersion();

Future<List<String>> get pedanticRules async => score_utils.pedanticRules;

Iterable<LintRule> get registeredLints {
  if (_registeredLints == null) {
    registerLintRules();
    _registeredLints = Registry.ruleRegistry;
  }
  return _registeredLints;
}

Future<List<String>> get sdkTags async => _sdkTags ??= await _fetchSdkTags();

Future<List<String>> get stagehandRules async =>
    _stagehandRules ??= await score_utils.fetchRules(_stagehandOptionsUrl);

Future<String> dartSdkForLinter(String version) async {
  var sdkVersions = <String>[];
  var sdks = await sdkTags;
  for (var sdk in sdks) {
    var linterVersion = await linterForDartSdk(sdk);
    if (linterVersion == version) {
      sdkVersions.add(sdk);
    }
  }

  sdkVersions.sort();
  return sdkVersions.isNotEmpty ? sdkVersions.first : null;
}

Future<List<String>> fetchRulesForVersion(String version) async =>
    score_utils.fetchRules(_repoPathPrefix.resolve('$version$_allPathSuffix'));

Future<String> findSinceDartSdk(String linterVersion) async =>
    await dartSdkForLinter(linterVersion);

Future<String> findSinceLinter(String lint) async {
  // History recorded in `all.yaml` starts in minor 31.
  var rules_31 = await rulesForVersion(31);
  if (rules_31.contains(lint)) {
    var version = await _crawlForVersion(lint);
    if (version != null) {
      return version;
    }
  }

  var latest = await latestMinor;
  for (var minor = 31; minor <= latest; ++minor) {
    var rules = await rulesForVersion(minor);
    if (rules != null) {
      if (rules.contains(lint)) {
        return '0.1.$minor';
      }
    }
  }

  return null;
}

Future<String> linterForDartSdk(String sdk) async =>
    _dartSdkToLinterMap[sdk] ??= await _fetchLinterForVersion(sdk);

Future<List<String>> rulesForVersion(int minor) async {
  var version = '0.1.$minor';
  if (minor >= 31) {
    return _sinceMap[version] ??= await fetchRulesForVersion(version);
  }
  return null;
}

Future<String> _crawlForVersion(String lint) async {
  var client = http.Client();
  for (var minor = 1; minor < 31; ++minor) {
    var version = '0.1.$minor';
    var req = await client
        .get(_rulePathPrefix.resolve('$version/lib/src/rules/$lint.dart'));
    if (req.statusCode == 200) {
      return version;
    }
  }
  return null;
}

Future<String> _fetchDEPSforVersion(String version) async {
  var client = http.Client();
  //https://raw.githubusercontent.com/dart-lang/sdk/2.1.0-dev.1.0/DEPS
  var req = await client.get(
      Uri.https('raw.githubusercontent.com', '/dart-lang/sdk/$version/DEPS'));
  return req.body;
}

Future<List<String>> _fetchEffectiveDartRules() async {
  var client = http.Client();
  var req = await client.get(_effectiveDartOptionsUrl);
  var includedOptions =
      req.body.split('include: package:effective_dart/')[1].trim();
  return score_utils
      .fetchRules(_effectiveDartOptionsRootUrl.resolve(includedOptions));
}

Future<String> _fetchLinterForVersion(String version) async {
  var deps = await _fetchDEPSforVersion(version);
  if (deps != null) {
    for (var line in deps.split('\n')) {
      if (line.trim().startsWith('"lint')) {
        // "linter_tag": "0.1.59",
        var split = line.trim().split('"linter_tag":');
        if (split.length == 2) {
          //  "0.1.59",
          return split[1].split('"')[1];
        }
      }
    }
  }
  return null;
}

Future<List<String>> _fetchSdkTags() {
  final github = GitHub();
  final slug = RepositorySlug('dart-lang', 'sdk');

  print('list repository tags: $slug');

  return github.repositories
      .listTags(slug)
      .map((t) => t.name)
      .where((t) {
        // Filter on numeric release tags.
        if (!t.startsWith(RegExp(r'\d+'))) {
          return false;
        }

        // Filter on bottom.
        try {
          var version = Version.parse(t);
          return version.compareTo(bottomDartSdk) >= 0;
        } on FormatException {
          return false;
        }
      })
      .toList()
      .catchError((e) {
        print('exception caught fetching SDK tags');
        print(e);
        print('(using cached SDK values)');
        return Future.value(<String>[]);
      });
}

Future<int> _readLatestMinorVersion() async {
  var contents = await File('pubspec.yaml').readAsString();
  final pubspec = loadYamlNode(contents) as YamlMap;
  // 0.1.79 or 0.1.79-dev or 0.1.97+1
  return int.parse((pubspec['version'] as String)
      .split('.')
      .last
      .split('-')
      .first
      .split('+')
      .first);
}
