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

import 'package:analyzer/dart/analysis/results.dart';
import 'package:analyzer/src/dart/analysis/performance_logger.dart';
import 'package:analyzer/src/dart/micro/cider_byte_store.dart';
import 'package:analyzer/src/dart/micro/resolve_file.dart';
import 'package:analyzer/src/test_utilities/find_element.dart';
import 'package:analyzer/src/test_utilities/find_node.dart';
import 'package:analyzer/src/test_utilities/mock_sdk.dart';
import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
import 'package:analyzer/src/workspace/bazel.dart';
import 'package:crypto/crypto.dart';
import 'package:linter/src/rules.dart';

import '../resolution/resolution.dart';

/// [FileResolver] based implementation of [ResolutionTest].
class FileResolutionTest with ResourceProviderMixin, ResolutionTest {
  static final String _testFile = '/workspace/dart/test/lib/test.dart';

  final CiderCachedByteStore byteStore =
      CiderCachedByteStore(20 * 1024 * 1024 /* 20 MB */);

  final StringBuffer logBuffer = StringBuffer();
  late PerformanceLog logger;
  late MockSdk sdk;

  late FileResolver fileResolver;

  @override
  void addTestFile(String content) {
    newFile(_testFile, content: content);
  }

  /// Create a new [FileResolver] into [fileResolver].
  ///
  /// We do this the first time, and to test reusing results from [byteStore].
  void createFileResolver() {
    var workspace = BazelWorkspace.find(
      resourceProvider,
      convertPath(_testFile),
    )!;

    byteStore.testView = CiderByteStoreTestView();
    fileResolver = FileResolver.from(
      logger: logger,
      resourceProvider: resourceProvider,
      byteStore: byteStore,
      sourceFactory: workspace.createSourceFactory(sdk, null),
      getFileDigest: (String path) => _getDigest(path),
      workspace: workspace,
      prefetchFiles: null,
    );
    fileResolver.testView = FileResolverTestView();
  }

  ErrorsResult getTestErrors() {
    var path = convertPath(_testFile);
    return fileResolver.getErrors(path: path);
  }

  @override
  Future<ResolvedUnitResult> resolveFile(String path) async {
    return fileResolver.resolve(path: path);
  }

  @override
  Future<void> resolveTestFile() async {
    var path = convertPath(_testFile);
    result = await resolveFile(path);
    findNode = FindNode(result.content!, result.unit!);
    findElement = FindElement(result.unit!);
  }

  void setUp() {
    registerLintRules();

    logger = PerformanceLog(logBuffer);
    sdk = MockSdk(resourceProvider: resourceProvider);

    newFile('/workspace/WORKSPACE', content: '');
    newFile('/workspace/dart/test/BUILD', content: '');
    createFileResolver();
  }

  String _getDigest(String path) {
    try {
      var content = resourceProvider.getFile(path).readAsStringSync();
      var contentBytes = utf8.encode(content);
      return md5.convert(contentBytes).toString();
    } catch (_) {
      return '';
    }
  }
}
