// Copyright (c) 2016, 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:path/path.dart' as path;
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';

import '../support/integration_tests.dart';

void main() {
  defineReflectiveSuite(() {
    defineReflectiveTests(AnalysisDomainGetErrorsTest);
  });
}

/// Tests that when an SDK path is specified on the command-line (via the
/// `--sdk` argument) that the specified SDK is used.
@reflectiveTest
class AnalysisDomainGetErrorsTest
    extends AbstractAnalysisServerIntegrationTest {
  String createNonStandardSdk() {
    var sdkPath = path.join(sourceDirectory.path, 'sdk');

    Directory(path.join(sdkPath, 'lib', 'core')).createSync(recursive: true);
    Directory(path.join(sdkPath, 'lib', 'async')).createSync(recursive: true);
    Directory(path.join(sdkPath, 'lib', 'fake')).createSync(recursive: true);

    File(path.join(sdkPath, 'version')).writeAsStringSync('2.12.0');

    File(path.join(sdkPath, 'lib', 'core', 'core.dart')).writeAsStringSync(r'''
library dart.core;
import 'dart:async';
class bool {}
class double {}
class int {}
class num {}
class Object {}
class Enum {}
class Iterable<E> {}
class Map<K, V> {}
class Null {}
class String {}
class Type {}
''');

    File(path.join(sdkPath, 'lib', 'async', 'async.dart'))
        .writeAsStringSync(r'''
library dart.async;
class Future<T> {}
''');

    File(path.join(sdkPath, 'lib', 'fake', 'fake.dart')).writeAsStringSync(r'''
class Fake {}
''');

    var libsInternalDir = path.join(sdkPath, 'lib', '_internal');
    Directory(libsInternalDir).createSync(recursive: true);

    File(path.join(sdkPath, 'lib', '_internal', 'allowed_experiments.json'))
        .writeAsStringSync('{}');

    var libsDir = path.join(libsInternalDir, 'sdk_library_metadata', 'lib');
    Directory(libsDir).createSync(recursive: true);

    File(path.join(libsDir, 'libraries.dart')).writeAsStringSync(r'''
final LIBRARIES = const <String, LibraryInfo> {
  "core":  const LibraryInfo("core/core.dart"),
  "async": const LibraryInfo("async/async.dart"),
  "fake":  const LibraryInfo("fake/fake.dart"),
};
''');

    return sdkPath;
  }

  @override
  Future startServer({int? diagnosticPort, int? servicesPort}) {
    var sdkPath = createNonStandardSdk();
    return server.start(
        diagnosticPort: diagnosticPort,
        sdkPath: sdkPath,
        servicesPort: servicesPort);
  }

  Future test_getErrors() async {
    var pathname = sourcePath('test.dart');
    var text = r'''
import 'dart:core';
import 'dart:fake';
''';
    writeFile(pathname, text);
    standardAnalysisSetup();
    await analysisFinished;
    var errors = existingErrorsForFile(pathname);
    expect(errors, hasLength(1));
    expect(errors[0].code, 'unused_import');
  }
}
