// Copyright (c) 2015, 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.

library analyzer_cli.test.driver;

import 'dart:async';
import 'dart:io';

import 'package:analyzer/error/error.dart';
import 'package:analyzer/source/analysis_options_provider.dart';
import 'package:analyzer/source/error_processor.dart';
import 'package:analyzer/src/error/codes.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/services/lint.dart';
import 'package:analyzer_cli/src/ansi.dart' as ansi;
import 'package:analyzer_cli/src/driver.dart';
import 'package:analyzer_cli/src/options.dart';
import 'package:cli_util/cli_util.dart' show getSdkDir;
import 'package:path/path.dart' as path;
import 'package:test/test.dart';
import 'package:yaml/src/yaml_node.dart';

import 'utils.dart';

main() {
  StringSink savedOutSink, savedErrorSink;
  int savedExitCode;
  ExitHandler savedExitHandler;

  /// Base setup.
  _setUp() {
    ansi.runningTests = true;
    savedOutSink = outSink;
    savedErrorSink = errorSink;
    savedExitHandler = exitHandler;
    savedExitCode = exitCode;
    exitHandler = (code) => exitCode = code;
    outSink = new StringBuffer();
    errorSink = new StringBuffer();
  }

  /// Base teardown.
  _tearDown() {
    outSink = savedOutSink;
    errorSink = savedErrorSink;
    exitCode = savedExitCode;
    exitHandler = savedExitHandler;
    ansi.runningTests = false;
  }

  setUp(() => _setUp());

  tearDown(() => _tearDown());

  group('Driver', () {
    group('options', () {
      test('todos', () async {
        await drive('data/file_with_todo.dart');
        expect(outSink.toString().contains('[info]'), isFalse);
      });
    });

    group('exit codes', () {
      test('fatal hints', () async {
        await drive('data/file_with_hint.dart', args: ['--fatal-hints']);
        expect(exitCode, 3);
      });

      test('not fatal hints', () async {
        await drive('data/file_with_hint.dart');
        expect(exitCode, 0);
      });

      test('fatal errors', () async {
        await drive('data/file_with_error.dart');
        expect(exitCode, 3);
      });

      test('not fatal warnings', () async {
        await drive('data/file_with_warning.dart');
        expect(exitCode, 0);
      });

      test('fatal warnings', () async {
        await drive('data/file_with_warning.dart', args: ['--fatal-warnings']);
        expect(exitCode, 3);
      });

      test('missing options file', () async {
        await drive('data/test_file.dart', options: 'data/NO_OPTIONS_HERE');
        expect(exitCode, 3);
      });

      test('missing dart file', () async {
        await drive('data/NO_DART_FILE_HERE.dart');
        expect(exitCode, 3);
      });

      test('part file', () async {
        await drive('data/library_and_parts/part2.dart');
        expect(exitCode, 3);
      });

      test('non-dangling part file', () async {
        Driver driver = new Driver();
        await driver.start([
          path.join(testDirectory, 'data/library_and_parts/lib.dart'),
          path.join(testDirectory, 'data/library_and_parts/part1.dart')
        ]);
        expect(exitCode, 0);
      });

      test('extra part file', () async {
        Driver driver = new Driver();
        await driver.start([
          path.join(testDirectory, 'data/library_and_parts/lib.dart'),
          path.join(testDirectory, 'data/library_and_parts/part1.dart'),
          path.join(testDirectory, 'data/library_and_parts/part2.dart')
        ]);
        expect(exitCode, 3);
      });

      test('bazel workspace relative path', () async {
        // Copy to temp dir so that existing analysis options
        // in the test directory hierarchy do not interfere
        await withTempDirAsync((String tempDirPath) async {
          String dartSdkPath = path.absolute(getSdkDir(<String>[]).path);
          await recursiveCopy(
              new Directory(path.join(testDirectory, 'data', 'bazel')),
              tempDirPath);
          Directory origWorkingDir = Directory.current;
          try {
            Directory.current = path.join(tempDirPath, 'proj');
            Driver driver = new Driver();
            try {
              await driver.start([
                path.join('lib', 'file.dart'),
                '--dart-sdk',
                dartSdkPath,
              ]);
            } catch (e) {
              print('=== debug info ===');
              print('dartSdkPath: $dartSdkPath');
              print('stderr:\n${errorSink.toString()}');
              rethrow;
            }
            expect(errorSink.toString(), isEmpty);
            expect(outSink.toString(), contains('No issues found'));
            expect(exitCode, 0);
          } finally {
            Directory.current = origWorkingDir;
          }
        });
      });
    });

    group('linter', () {
      void createTests(String designator, String optionsFileName) {
        group('lints in options - $designator', () {
          // Shared lint command.
          Future<Null> runLinter() async {
            return await drive('data/linter_project/test_file.dart',
                options: 'data/linter_project/$optionsFileName',
                args: ['--lints']);
          }

          test('gets analysis options', () async {
            await runLinter();

            /// Lints should be enabled.
            expect(driver.context.analysisOptions.lint, isTrue);

            /// The analysis options file only specifies 'camel_case_types'.
            var lintNames = getLints(driver.context).map((r) => r.name);
            expect(lintNames, orderedEquals(['camel_case_types']));
          });

          test('generates lints', () async {
            await runLinter();
            expect(_bulletToDash(outSink),
                contains('lint - Name types using UpperCamelCase'));
          });
        });

        group('default lints - $designator', () {
          // Shared lint command.
          Future<Null> runLinter() async {
            return await drive('data/linter_project/test_file.dart',
                options: 'data/linter_project/$optionsFileName',
                args: ['--lints']);
          }

          test('gets default lints', () async {
            await runLinter();

            /// Lints should be enabled.
            expect(driver.context.analysisOptions.lint, isTrue);

            /// Default list should include camel_case_types.
            var lintNames = getLints(driver.context).map((r) => r.name);
            expect(lintNames, contains('camel_case_types'));
          });

          test('generates lints', () async {
            await runLinter();
            expect(_bulletToDash(outSink),
                contains('lint - Name types using UpperCamelCase'));
          });
        });

        group('no `--lints` flag (none in options) - $designator', () {
          // Shared lint command.
          Future<Null> runLinter() async {
            return await drive('data/no_lints_project/test_file.dart',
                options: 'data/no_lints_project/$optionsFileName');
          }

          test('lints disabled', () async {
            await runLinter();
            expect(driver.context.analysisOptions.lint, isFalse);
          });

          test('no registered lints', () async {
            await runLinter();
            expect(getLints(driver.context), isEmpty);
          });

          test('no generated warnings', () async {
            await runLinter();
            expect(outSink.toString(), contains('No issues found'));
          });
        });
      }

      createTests('old', AnalysisEngine.ANALYSIS_OPTIONS_FILE);
      createTests('new', AnalysisEngine.ANALYSIS_OPTIONS_YAML_FILE);
    });

    test('containsLintRuleEntry', () {
      Map<String, YamlNode> options;
      options = parseOptions('''
linter:
  rules:
    - foo
        ''');
      expect(containsLintRuleEntry(options), true);
      options = parseOptions('''
        ''');
      expect(containsLintRuleEntry(options), false);
      options = parseOptions('''
linter:
  rules:
    # - foo
        ''');
      expect(containsLintRuleEntry(options), true);
      options = parseOptions('''
linter:
 # rules:
    # - foo
        ''');
      expect(containsLintRuleEntry(options), false);
    });

    group('options processing', () {
      void createTests(String designator, String optionsFileName) {
        group('basic config - $designator', () {
          // Shared driver command.
          Future<Null> doDrive() async {
            await drive('data/options_tests_project/test_file.dart',
                options: 'data/options_tests_project/$optionsFileName');
          }

          test('filters', () async {
            await doDrive();
            expect(processors, hasLength(3));

            // unused_local_variable: ignore
            var unused_local_variable = new AnalysisError(
                new TestSource(), 0, 1, HintCode.UNUSED_LOCAL_VARIABLE, [
              ['x']
            ]);
            expect(processorFor(unused_local_variable).severity, isNull);

            // missing_return: error
            var missing_return = new AnalysisError(
                new TestSource(), 0, 1, HintCode.MISSING_RETURN, [
              ['x']
            ]);
            expect(processorFor(missing_return).severity, ErrorSeverity.ERROR);
            expect(
                _bulletToDash(outSink),
                contains(
                    "error - This function declares a return type of 'int'"));
            expect(
                outSink.toString(), contains("1 error and 1 warning found."));
          });

          test('language', () async {
            await doDrive();
            expect(driver.context.analysisOptions.enableSuperMixins, isTrue);
          });

          test('strongMode', () async {
            await doDrive();
            expect(driver.context.analysisOptions.strongMode, isTrue);
            //https://github.com/dart-lang/sdk/issues/26129
            AnalysisContext sdkContext =
                driver.context.sourceFactory.dartSdk.context;
            expect(sdkContext.analysisOptions.strongMode, isTrue);
          });
        });

        group('with flags - $designator', () {
          // Shared driver command.
          Future<Null> doDrive() async {
            await drive('data/options_tests_project/test_file.dart',
                args: ['--fatal-warnings'],
                options: 'data/options_tests_project/$optionsFileName');
          }

          test('override fatal warning', () async {
            await doDrive();
            // missing_return: error
            var undefined_function = new AnalysisError(new TestSource(), 0, 1,
                StaticTypeWarningCode.UNDEFINED_FUNCTION, [
              ['x']
            ]);
            expect(processorFor(undefined_function).severity,
                ErrorSeverity.WARNING);
            // Should not be made fatal by `--fatal-warnings`.
            expect(_bulletToDash(outSink),
                contains("warning - The function 'baz' isn't defined"));
            expect(
                outSink.toString(), contains("1 error and 1 warning found."));
          });
        });
      }

      createTests('old', AnalysisEngine.ANALYSIS_OPTIONS_FILE);
      createTests('new', AnalysisEngine.ANALYSIS_OPTIONS_YAML_FILE);

      test('include directive', () async {
        String testDir = path.join(
            testDirectory, 'data', 'options_include_directive_tests_project');
        await drive(
          path.join(testDir, 'lib', 'test_file.dart'),
          args: [
            '--fatal-warnings',
            '--packages',
            path.join(testDir, '_packages'),
          ],
          options: path.join(testDir, '.analysis_options'),
        );
        expect(exitCode, 3);
        expect(outSink.toString(),
            contains('but doesn\'t end with a return statement'));
        expect(outSink.toString(), contains('isn\'t defined'));
        expect(outSink.toString(), contains('Avoid empty else statements'));
      });

      test('test strong SDK', () async {
        String testDir = path.join(testDirectory, 'data', 'strong_sdk');
        await drive(path.join(testDir, 'main.dart'), args: ['--strong']);
        expect(driver.context.analysisOptions.strongMode, isTrue);
        expect(outSink.toString(), contains('No issues found'));
        expect(exitCode, 0);
      });
    });

    void createTests(String designator, String optionsFileName) {
      group('build-mode - $designator', () {
        // Shared driver command.
        Future<Null> doDrive(String filePath,
            {List<String> additionalArgs: const []}) async {
          await drive('file:///test_file.dart|$filePath',
              args: [
                '--dart-sdk',
                findSdkDirForSummaries(),
                '--build-mode',
                '--format=machine'
              ]..addAll(additionalArgs),
              options: 'data/options_tests_project/$optionsFileName');
        }

        test('no stats', () async {
          await doDrive(path.join('data', 'test_file.dart'));
          // Should not print stat summary.
          expect(outSink.toString(), isEmpty);
          expect(errorSink.toString(), isEmpty);
          expect(exitCode, 0);
        });

        test(
            'Fails if file not found, even when --build-suppress-exit-code is given',
            () async {
          await doDrive(path.join('data', 'non_existent_file.dart'),
              additionalArgs: ['--build-suppress-exit-code']);
          expect(exitCode, isNot(0));
        });

        test('Fails if there are errors', () async {
          await doDrive(path.join('data', 'file_with_error.dart'));
          expect(exitCode, isNot(0));
        });

        test(
            'Succeeds if there are errors, when --build-suppress-exit-code is given',
            () async {
          await doDrive(path.join('data', 'file_with_error.dart'),
              additionalArgs: ['--build-suppress-exit-code']);
          expect(exitCode, 0);
        });
      });
    }

    createTests('old', AnalysisEngine.ANALYSIS_OPTIONS_FILE);
    createTests('new', AnalysisEngine.ANALYSIS_OPTIONS_YAML_FILE);

//TODO(pq): fix to be bot-friendly (sdk#25258).
//    group('in temp directory', () {
//      Directory savedCurrentDirectory;
//      Directory tempDir;
//      setUp(() {
//        // Call base setUp.
//        _setUp();
//        savedCurrentDirectory = Directory.current;
//        tempDir = Directory.systemTemp.createTempSync('analyzer_');
//      });
//      tearDown(() {
//        Directory.current = savedCurrentDirectory;
//        tempDir.deleteSync(recursive: true);
//        // Call base tearDown.
//        _tearDown();
//      });
//
//      test('packages folder', () {
//        Directory.current = tempDir;
//        new File(path.join(tempDir.path, 'test.dart')).writeAsStringSync('''
//import 'package:foo/bar.dart';
//main() {
//  baz();
//}
//        ''');
//        Directory packagesDir =
//            new Directory(path.join(tempDir.path, 'packages'));
//        packagesDir.createSync();
//        Directory fooDir = new Directory(path.join(packagesDir.path, 'foo'));
//        fooDir.createSync();
//        new File(path.join(fooDir.path, 'bar.dart')).writeAsStringSync('''
//void baz() {}
//        ''');
//        new Driver().start(['test.dart']);
//        expect(exitCode, 0);
//      });
//
//      test('no package resolution', () {
//        Directory.current = tempDir;
//        new File(path.join(tempDir.path, 'test.dart')).writeAsStringSync('''
//import 'package:path/path.dart';
//main() {}
//        ''');
//        new Driver().start(['test.dart']);
//        expect(exitCode, 3);
//        String stdout = outSink.toString();
//        expect(stdout, contains('[error] Target of URI does not exist'));
//        expect(stdout, contains('1 error found.'));
//        expect(errorSink.toString(), '');
//      });
//
//      test('bad package root', () {
//        new Driver().start(['--package-root', 'does/not/exist', 'test.dart']);
//        String stdout = outSink.toString();
//        expect(exitCode, 3);
//        expect(
//            stdout,
//            contains(
//                'Package root directory (does/not/exist) does not exist.'));
//      });
//    });
  });
}

const emptyOptionsFile = 'data/empty_options.yaml';

/// Shared driver.
Driver driver;

List<ErrorProcessor> get processors =>
    driver.context.analysisOptions.errorProcessors;

/// Convert a file specification from a relative path to an absolute path.
/// Handles the case where the file specification is of the form "$uri|$path".
String adjustFileSpec(String fileSpec) {
  int uriPrefixLength = fileSpec.indexOf('|') + 1;
  String uriPrefix = fileSpec.substring(0, uriPrefixLength);
  String relativePath = fileSpec.substring(uriPrefixLength);
  return '$uriPrefix${path.join(testDirectory, relativePath)}';
}

/// Start a driver for the given [source], optionally providing additional
/// [args] and an [options] file path.  The value of [options] defaults to
/// an empty options file to avoid unwanted configuration from an otherwise
/// discovered options file.
Future<Null> drive(String source,
    {String options: emptyOptionsFile,
    List<String> args: const <String>[]}) async {
  driver = new Driver();
  var cmd = [
    '--options',
    path.join(testDirectory, options),
    adjustFileSpec(source)
  ]..addAll(args);
  await driver.start(cmd);
}

/// Try to find a appropriate directory to pass to "--dart-sdk" that will
/// allow summaries to be found.
String findSdkDirForSummaries() {
  Set<String> triedDirectories = new Set<String>();
  bool isSuitable(String sdkDir) {
    triedDirectories.add(sdkDir);
    return new File(path.join(sdkDir, 'lib', '_internal', 'spec.sum'))
        .existsSync();
  }

  // Usually the sdk directory is the parent of the parent of the "dart"
  // executable.
  Directory executableParent = new File(Platform.executable).parent;
  Directory executableGrandparent = executableParent.parent;
  if (isSuitable(executableGrandparent.path)) {
    return executableGrandparent.path;
  }
  // During buildbot execution, the sdk directory is simply the parent of the
  // "dart" executable.
  if (isSuitable(executableParent.path)) {
    return executableParent.path;
  }
  // If neither of those are suitable, assume we are running locally within the
  // SDK project (e.g. within an IDE).  Find the build output directory and
  // search all built configurations.
  Directory sdkRootDir =
      new File(Platform.script.toFilePath()).parent.parent.parent.parent;
  for (String outDirName in ['out', 'xcodebuild']) {
    Directory outDir = new Directory(path.join(sdkRootDir.path, outDirName));
    if (outDir.existsSync()) {
      for (FileSystemEntity subdir in outDir.listSync()) {
        if (subdir is Directory) {
          String candidateSdkDir = path.join(subdir.path, 'dart-sdk');
          if (isSuitable(candidateSdkDir)) {
            return candidateSdkDir;
          }
        }
      }
    }
  }
  throw new Exception('Could not find an SDK directory containing summaries.'
      '  Tried: ${triedDirectories.toList()}');
}

Map<String, YamlNode> parseOptions(String src) =>
    new AnalysisOptionsProvider().getOptionsFromString(src);

ErrorProcessor processorFor(AnalysisError error) =>
    processors.firstWhere((p) => p.appliesTo(error));

class TestSource implements Source {
  TestSource();

  @override
  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
}

/// Normalize text with bullets.
String _bulletToDash(item) => '$item'.replaceAll('•', '-');
