// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import 'package:flutter_tools/src/base/error_handling_io.dart';
import 'package:flutter_tools/src/base/user_messages.dart';
import 'package:flutter_tools/src/globals.dart' as globals;
import 'package:flutter_tools/src/artifacts.dart';
import 'package:flutter_tools/src/base/common.dart';
import 'package:flutter_tools/src/base/file_system.dart';
import 'package:flutter_tools/src/base/io.dart';
import 'package:flutter_tools/src/base/logger.dart';
import 'package:flutter_tools/src/base/platform.dart';
import 'package:flutter_tools/src/base/terminal.dart';
import 'package:flutter_tools/src/cache.dart';
import 'package:flutter_tools/src/commands/analyze.dart';
import 'package:flutter_tools/src/runner/flutter_command.dart';
import 'package:process/process.dart';

import '../../src/common.dart';
import '../../src/context.dart';

final Platform _kNoColorTerminalPlatform = FakePlatform(
  stdoutSupportsAnsi: false);

void main() {
  String analyzerSeparator;
  FileSystem fileSystem;
  Platform platform;
  BufferLogger logger;
  AnsiTerminal terminal;
  ProcessManager processManager;
  Directory tempDir;
  String projectPath;
  File libMain;
  Artifacts artifacts;

  Future<void> runCommand({
    FlutterCommand command,
    List<String> arguments,
    List<String> statusTextContains,
    List<String> errorTextContains,
    bool toolExit = false,
    String exitMessageContains,
    int exitCode = 0,
  }) async {
    try {
      arguments.insert(0, '--flutter-root=${Cache.flutterRoot}');
      await createTestCommandRunner(command).run(arguments);
      expect(toolExit, isFalse, reason: 'Expected ToolExit exception');
    } on ToolExit catch (e) {
      if (!toolExit) {
        testLogger.clear();
        rethrow;
      }
      if (exitMessageContains != null) {
        expect(e.message, contains(exitMessageContains));
        // May not analyzer exception the `exitCode` is `null`.
        expect(e.exitCode ?? 0, exitCode);
      }
    }
    assertContains(logger.statusText, statusTextContains);
    assertContains(logger.errorText, errorTextContains);

    logger.clear();
  }

  void _createDotPackages(String projectPath, [bool nullSafe = false]) {
    final StringBuffer flutterRootUri = StringBuffer('file://');
    final String canonicalizedFlutterRootPath = fileSystem.path.canonicalize(Cache.flutterRoot);
    if (platform.isWindows) {
      flutterRootUri
          ..write('/')
          ..write(canonicalizedFlutterRootPath.replaceAll(r'\', '/'));
    } else {
      flutterRootUri.write(canonicalizedFlutterRootPath);
    }
    final String dotPackagesSrc = '''
{
  "configVersion": 2,
  "packages": [
    {
      "name": "flutter",
      "rootUri": "$flutterRootUri/packages/flutter",
      "packageUri": "lib/",
      "languageVersion": "2.10"
    },
    {
      "name": "sky_engine",
      "rootUri": "$flutterRootUri/bin/cache/pkg/sky_engine",
      "packageUri": "lib/",
      "languageVersion": "2.10"
    },
    {
      "name": "flutter_project",
      "rootUri": "../",
      "packageUri": "lib/",
      "languageVersion": "${nullSafe ? "2.10" : "2.7"}"
    }
  ]
}
''';

    fileSystem.file(fileSystem.path.join(projectPath, '.dart_tool', 'package_config.json'))
      ..createSync(recursive: true)
      ..writeAsStringSync(dotPackagesSrc);
  }

  setUpAll(() {
    Cache.disableLocking();
    processManager = const LocalProcessManager();
    platform = const LocalPlatform();
    terminal = AnsiTerminal(platform: platform, stdio: Stdio());
    fileSystem = LocalFileSystem.instance;
    logger = BufferLogger(
      outputPreferences: OutputPreferences.test(),
      terminal: terminal,
    );
    analyzerSeparator = platform.isWindows ? '-' : '•';
    artifacts = CachedArtifacts(
      cache: globals.cache,
      fileSystem: fileSystem,
      platform: platform,
    );
    Cache.flutterRoot = Cache.defaultFlutterRoot(
      fileSystem: fileSystem,
      platform: platform,
      userMessages: UserMessages(),
    );
  });

  setUp(() {
    tempDir = fileSystem.systemTempDirectory.createTempSync(
      'flutter_analyze_once_test_1.',
    ).absolute;
    projectPath = fileSystem.path.join(tempDir.path, 'flutter_project');
    fileSystem.file(fileSystem.path.join(projectPath, 'pubspec.yaml'))
        ..createSync(recursive: true)
        ..writeAsStringSync(pubspecYamlSrc);
    _createDotPackages(projectPath);
    libMain = fileSystem.file(fileSystem.path.join(projectPath, 'lib', 'main.dart'))
        ..createSync(recursive: true)
        ..writeAsStringSync(mainDartSrc);
  });

  tearDown(() {
    tryToDelete(tempDir);
  });

  // Analyze in the current directory - no arguments
  testUsingContext('working directory', () async {
    await runCommand(
      command: AnalyzeCommand(
        workingDirectory: fileSystem.directory(projectPath),
        fileSystem: fileSystem,
        logger: logger,
        platform: platform,
        processManager: processManager,
        terminal: terminal,
        artifacts: artifacts,
      ),
      arguments: <String>['analyze', '--no-pub'],
      statusTextContains: <String>['No issues found!'],
    );
  });

  // Analyze a specific file outside the current directory
  testUsingContext('passing one file throws', () async {
    await runCommand(
      command: AnalyzeCommand(
        platform: platform,
        fileSystem: fileSystem,
        logger: logger,
        processManager: processManager,
        terminal: terminal,
        artifacts: artifacts,
      ),
      arguments: <String>['analyze', '--no-pub', libMain.path],
      toolExit: true,
      exitMessageContains: 'is not a directory',
    );
  });

  // Analyze in the current directory - no arguments
  testUsingContext('working directory with errors', () async {
    // Break the code to produce the "Avoid empty else" hint
    // that is upgraded to a warning in package:flutter/analysis_options_user.yaml
    // to assert that we are using the default Flutter analysis options.
    // Also insert a statement that should not trigger a lint here
    // but will trigger a lint later on when an analysis_options.yaml is added.
    String source = await libMain.readAsString();
    source = source.replaceFirst(
      'return MaterialApp(',
      'if (debugPrintRebuildDirtyWidgets) {} else ; return MaterialApp(',
    );
    source = source.replaceFirst(
      'onPressed: _incrementCounter,',
      '// onPressed: _incrementCounter,',
    );
    source = source.replaceFirst(
        '_counter++;',
        '_counter++; throw "an error message";',
      );
    libMain.writeAsStringSync(source);

    // Analyze in the current directory - no arguments
    await runCommand(
      command: AnalyzeCommand(
        workingDirectory: fileSystem.directory(projectPath),
        platform: platform,
        fileSystem: fileSystem,
        logger: logger,
        processManager: processManager,
        terminal: terminal,
        artifacts: artifacts,
      ),
      arguments: <String>['analyze', '--no-pub'],
      statusTextContains: <String>[
        'Analyzing',
        'info $analyzerSeparator Avoid empty else statements',
        'info $analyzerSeparator Avoid empty statements',
        'info $analyzerSeparator The declaration \'_incrementCounter\' isn\'t',
        'warning $analyzerSeparator The parameter \'onPressed\' is required',
      ],
      exitMessageContains: '4 issues found.',
      toolExit: true,
      exitCode: 1,
    );
  });

  // Analyze in the current directory - no arguments
  testUsingContext('working directory with local options', () async {
    // Insert an analysis_options.yaml file in the project
    // which will trigger a lint for broken code that was inserted earlier
    final File optionsFile = fileSystem.file(fileSystem.path.join(projectPath, 'analysis_options.yaml'));
    try {
      optionsFile.writeAsStringSync('''
  include: package:flutter/analysis_options_user.yaml
  linter:
    rules:
      - only_throw_errors
  ''');
      String source = libMain.readAsStringSync();
      source = source.replaceFirst(
        'onPressed: _incrementCounter,',
        '// onPressed: _incrementCounter,',
      );
      source = source.replaceFirst(
        '_counter++;',
        '_counter++; throw "an error message";',
      );
      libMain.writeAsStringSync(source);

      // Analyze in the current directory - no arguments
      await runCommand(
        command: AnalyzeCommand(
          workingDirectory: fileSystem.directory(projectPath),
          platform: platform,
          fileSystem: fileSystem,
          logger: logger,
          processManager: processManager,
          terminal: terminal,
          artifacts: artifacts,
        ),
        arguments: <String>['analyze', '--no-pub'],
        statusTextContains: <String>[
          'Analyzing',
          'info $analyzerSeparator The declaration \'_incrementCounter\' isn\'t',
          'info $analyzerSeparator Only throw instances of classes extending either Exception or Error',
          'warning $analyzerSeparator The parameter \'onPressed\' is required',
        ],
        exitMessageContains: '3 issues found.',
        toolExit: true,
        exitCode: 1,
      );
    } finally {
      ErrorHandlingFileSystem.deleteIfExists(optionsFile);
    }
  });

  testUsingContext('analyze once no duplicate issues', () async {
    final Directory tempDir = fileSystem.systemTempDirectory.createTempSync('flutter_analyze_once_test_2.').absolute;
    _createDotPackages(tempDir.path);

    try {
      final File foo = fileSystem.file(fileSystem.path.join(tempDir.path, 'foo.dart'));
      foo.writeAsStringSync('''
import 'bar.dart';

void foo() => bar();
''');

      final File bar = fileSystem.file(fileSystem.path.join(tempDir.path, 'bar.dart'));
      bar.writeAsStringSync('''
import 'dart:async'; // unused

void bar() {
}
''');

      // Analyze in the current directory - no arguments
      await runCommand(
        command: AnalyzeCommand(
          workingDirectory: tempDir,
          platform: platform,
          fileSystem: fileSystem,
          logger: logger,
          processManager: processManager,
          terminal: terminal,
          artifacts: artifacts,
        ),
        arguments: <String>['analyze', '--no-pub'],
        statusTextContains: <String>[
          'Analyzing',
        ],
        exitMessageContains: '1 issue found.',
        toolExit: true,
        exitCode: 1
      );
    } finally {
      tryToDelete(tempDir);
    }
  });

  testUsingContext('analyze once returns no issues when source is error-free', () async {
    const String contents = '''
StringBuffer bar = StringBuffer('baz');
''';
    final Directory tempDir = fileSystem.systemTempDirectory.createTempSync('flutter_analyze_once_test_3.');
    _createDotPackages(tempDir.path);

    tempDir.childFile('main.dart').writeAsStringSync(contents);
    try {
      await runCommand(
        command: AnalyzeCommand(
          workingDirectory: fileSystem.directory(tempDir),
          platform: _kNoColorTerminalPlatform,
          fileSystem: fileSystem,
          logger: logger,
          processManager: processManager,
          terminal: terminal,
          artifacts: artifacts,
        ),
        arguments: <String>['analyze', '--no-pub'],
        statusTextContains: <String>['No issues found!'],
      );
    } finally {
      tryToDelete(tempDir);
    }
  });

  testUsingContext('analyze once supports analyzing null-safe code', () async {
    const String contents = '''
int? bar;
''';
    final Directory tempDir = fileSystem.systemTempDirectory.createTempSync('flutter_analyze_once_test_null_safety.');
    _createDotPackages(tempDir.path, true);

    tempDir.childFile('main.dart').writeAsStringSync(contents);
    try {
      await runCommand(
        command: AnalyzeCommand(
          workingDirectory: fileSystem.directory(tempDir),
          platform: _kNoColorTerminalPlatform,
          fileSystem: fileSystem,
          logger: logger,
          processManager: processManager,
          terminal: terminal,
          artifacts: artifacts,
        ),
        arguments: <String>['analyze', '--no-pub', '--enable-experiment=non-nullable'],
        statusTextContains: <String>['No issues found!'],
      );
    } finally {
      tryToDelete(tempDir);
    }
  });

  testUsingContext('analyze once returns no issues for todo comments', () async {
    const String contents = '''
// TODO(foobar):
StringBuffer bar = StringBuffer('baz');
''';
    final Directory tempDir = fileSystem.systemTempDirectory.createTempSync('flutter_analyze_once_test_4.');
    _createDotPackages(tempDir.path);

    tempDir.childFile('main.dart').writeAsStringSync(contents);
    try {
      await runCommand(
        command: AnalyzeCommand(
          workingDirectory: fileSystem.directory(tempDir),
          platform: _kNoColorTerminalPlatform,
          terminal: terminal,
          processManager: processManager,
          logger: logger,
          fileSystem: fileSystem,
          artifacts: artifacts,
        ),
        arguments: <String>['analyze', '--no-pub'],
        statusTextContains: <String>['No issues found!'],
      );
    } finally {
      tryToDelete(tempDir);
    }
  });

  testUsingContext('analyze once with default options has info issue finally exit code 1.', () async {
    final Directory tempDir = fileSystem.systemTempDirectory.createTempSync(
        'flutter_analyze_once_default_options_info_issue_exit_code_1.');
    _createDotPackages(tempDir.path);

    const String infoSourceCode = '''
int analyze() {}
''';

    tempDir.childFile('main.dart').writeAsStringSync(infoSourceCode);
    try {
      await runCommand(
        command: AnalyzeCommand(
          workingDirectory: fileSystem.directory(tempDir),
          platform: _kNoColorTerminalPlatform,
          terminal: terminal,
          processManager: processManager,
          logger: logger,
          fileSystem: fileSystem,
          artifacts: artifacts,
        ),
        arguments: <String>['analyze', '--no-pub'],
        statusTextContains: <String>[
          'info',
          'missing_return',
        ],
        exitMessageContains: '1 issue found.',
        toolExit: true,
        exitCode: 1,
      );
    } finally {
      tryToDelete(tempDir);
    }
  });

  testUsingContext('analyze once with no-fatal-infos has info issue finally exit code 0.', () async {
    final Directory tempDir = fileSystem.systemTempDirectory.createTempSync(
        'flutter_analyze_once_no_fatal_infos_info_issue_exit_code_0.');
    _createDotPackages(tempDir.path);

    const String infoSourceCode = '''
int analyze() {}
''';

    tempDir.childFile('main.dart').writeAsStringSync(infoSourceCode);
    try {
      await runCommand(
        command: AnalyzeCommand(
          workingDirectory: fileSystem.directory(tempDir),
          platform: _kNoColorTerminalPlatform,
          terminal: terminal,
          processManager: processManager,
          logger: logger,
          fileSystem: fileSystem,
          artifacts: artifacts,
        ),
        arguments: <String>['analyze', '--no-pub', '--no-fatal-infos'],
        statusTextContains: <String>[
          'info',
          'missing_return',
        ],
        exitMessageContains: '1 issue found.',
        toolExit: true,
        exitCode: 0,
      );
    } finally {
      tryToDelete(tempDir);
    }
  });

  testUsingContext('analyze once only fatal-warnings has info issue finally exit code 0.', () async {
    final Directory tempDir = fileSystem.systemTempDirectory.createTempSync(
        'flutter_analyze_once_only_fatal_warnings_info_issue_exit_code_0.');
    _createDotPackages(tempDir.path);

    const String infoSourceCode = '''
int analyze() {}
''';

    tempDir.childFile('main.dart').writeAsStringSync(infoSourceCode);
    try {
      await runCommand(
        command: AnalyzeCommand(
          workingDirectory: fileSystem.directory(tempDir),
          platform: _kNoColorTerminalPlatform,
          terminal: terminal,
          processManager: processManager,
          logger: logger,
          fileSystem: fileSystem,
          artifacts: artifacts,
        ),
        arguments: <String>['analyze', '--no-pub', '--fatal-warnings', '--no-fatal-infos'],
        statusTextContains: <String>[
          'info',
          'missing_return',
        ],
        exitMessageContains: '1 issue found.',
        toolExit: true,
        exitCode: 0,
      );
    } finally {
      tryToDelete(tempDir);
    }
  });

  testUsingContext('analyze once only fatal-infos has warning issue finally exit code 1.', () async {
    final Directory tempDir = fileSystem.systemTempDirectory.createTempSync(
        'flutter_analyze_once_only_fatal_infos_warning_issue_exit_code_1.');
    _createDotPackages(tempDir.path);

    const String warningSourceCode = '''
int analyze() {}
''';

    final File optionsFile = fileSystem.file(fileSystem.path.join(tempDir.path, 'analysis_options.yaml'));
    optionsFile.writeAsStringSync('''
analyzer:
  errors:
    missing_return: warning
  ''');

    tempDir.childFile('main.dart').writeAsStringSync(warningSourceCode);
    try {
      await runCommand(
        command: AnalyzeCommand(
          workingDirectory: fileSystem.directory(tempDir),
          platform: _kNoColorTerminalPlatform,
          terminal: terminal,
          processManager: processManager,
          logger: logger,
          fileSystem: fileSystem,
          artifacts: artifacts,
        ),
        arguments: <String>['analyze','--no-pub', '--fatal-infos', '--no-fatal-warnings'],
        statusTextContains: <String>[
          'warning',
          'missing_return',
        ],
        exitMessageContains: '1 issue found.',
        toolExit: true,
        exitCode: 1,
      );
    } finally {
      tryToDelete(tempDir);
    }
  });
}

void assertContains(String text, List<String> patterns) {
  if (patterns != null) {
    for (final String pattern in patterns) {
      expect(text, contains(pattern));
    }
  }
}

const String mainDartSrc = r'''
import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  int _counter = 0;

  void _incrementCounter() {
    setState(() {
      _counter++;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(
              'You have pushed the button this many times:',
            ),
            Text(
              '$_counter',
              style: Theme.of(context).textTheme.headline4,
            ),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip: 'Increment',
        child: Icon(Icons.add),
      ),
    );
  }
}
''';

const String pubspecYamlSrc = r'''
name: flutter_project
environment:
  sdk: ">=2.1.0 <3.0.0"

dependencies:
  flutter:
    sdk: flutter
''';
