// 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:io';

import 'package:analyzer/error/error.dart';
import 'package:analyzer/plugin/options.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/driver.dart';
import 'package:analyzer_cli/src/options.dart';
import 'package:path/path.dart' as path;
import 'package:plugin/plugin.dart';
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() {
    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;
  }

  setUp(() => _setUp());

  tearDown(() => _tearDown());

  group('Driver', () {
    group('options', () {
      test('custom processor', () {
        Driver driver = new Driver();
        TestProcessor processor = new TestProcessor();
        driver.userDefinedPlugins = [new TestPlugin(processor)];
        driver.start([
          '--options',
          path.join(testDirectory, 'data/test_options.yaml'),
          path.join(testDirectory, 'data/test_file.dart')
        ]);
        expect(processor.options['test_plugin'], isNotNull);
        expect(processor.exception, isNull);
      });
      test('todos', () {
        drive('data/file_with_todo.dart');
        expect(outSink.toString().contains('[info]'), isFalse);
      });
    });

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

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

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

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

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

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

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

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

      test('non-dangling part file', () {
        Driver driver = new Driver();
        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', () {
        Driver driver = new Driver();
        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);
      });
    });

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

          test('gets analysis options', () {
            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', () {
            runLinter();
            expect(outSink.toString(),
                contains('[lint] Name types using UpperCamelCase.'));
          });
        });

        group('default lints - $designator', () {
          // Shared lint command.
          void runLinter() => drive('data/linter_project/test_file.dart',
              options: 'data/linter_project/$optionsFileName',
              args: ['--lints']);

          test('gets default lints', () {
            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', () {
            runLinter();
            expect(outSink.toString(),
                contains('[lint] Name types using UpperCamelCase.'));
          });
        });

        group('no `--lints` flag (none in options) - $designator', () {
          // Shared lint command.
          void runLinter() => drive('data/no_lints_project/test_file.dart',
              options: 'data/no_lints_project/$optionsFileName');

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

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

          test('no generated warnings', () {
            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.
          void doDrive() => drive('data/options_tests_project/test_file.dart',
              options: 'data/options_tests_project/$optionsFileName');

          test('filters', () {
            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(
                outSink.toString(),
                contains(
                    "[error] This function declares a return type of 'int'"));
            expect(
                outSink.toString(), contains("1 error and 1 warning found."));
          });

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

          test('strongMode', () {
            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.
          void doDrive() => drive('data/options_tests_project/test_file.dart',
              args: ['--fatal-warnings'],
              options: 'data/options_tests_project/$optionsFileName');

          test('override fatal warning', () {
            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(outSink.toString(),
                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);
    });

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

        test('no stats', () {
          doDrive('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',
            () {
          doDrive('data/non_existent_file.dart',
              additionalArgs: ['--build-suppress-exit-code']);
          expect(exitCode, isNot(0));
        });

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

        test(
            'Succeeds if there are errors, when --build-suppress-exit-code is given',
            () {
          doDrive('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.
void drive(String source,
    {String options: emptyOptionsFile, List<String> args: const <String>[]}) {
  driver = new Driver();
  var cmd = [
    '--options',
    path.join(testDirectory, options),
    adjustFileSpec(source)
  ]..addAll(args);
  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 TestPlugin extends Plugin {
  TestProcessor processor;
  TestPlugin(this.processor);

  @override
  String get uniqueIdentifier => 'test_plugin.core';

  @override
  void registerExtensionPoints(RegisterExtensionPoint register) {
    // None
  }

  @override
  void registerExtensions(RegisterExtension register) {
    register(OPTIONS_PROCESSOR_EXTENSION_POINT_ID, processor);
  }
}

class TestProcessor extends OptionsProcessor {
  Map<String, Object> options;
  Exception exception;

  @override
  void onError(Exception exception) {
    this.exception = exception;
  }

  @override
  void optionsProcessed(AnalysisContext context, Map<String, Object> options) {
    this.options = options;
  }
}

class TestSource implements Source {
  TestSource();

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