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

import 'package:platform/platform.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/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:flutter_tools/src/runner/flutter_command_runner.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;

  Future<void> runCommand({
    FlutterCommand command,
    List<String> arguments,
    List<String> statusTextContains,
    List<String> errorTextContains,
    bool toolExit = false,
    String exitMessageContains,
  }) 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));
      }
    }
    assertContains(logger.statusText, statusTextContains);
    assertContains(logger.errorText, errorTextContains);

    logger.clear();
  }

  void _createDotPackages(String projectPath) {
    final StringBuffer flutterRootUri = StringBuffer('file://');
    final String canonicalizedFlutterRootPath = fileSystem.path.canonicalize(Cache.flutterRoot);
    if (platform.isWindows) {
      flutterRootUri
          ..write('/')
          ..write(canonicalizedFlutterRootPath.replaceAll('\\', '/'));
    } else {
      flutterRootUri.write(canonicalizedFlutterRootPath);
    }
    final String dotPackagesSrc = '''# Generated
flutter:$flutterRootUri/packages/flutter/lib/
sky_engine:$flutterRootUri/bin/cache/pkg/sky_engine/lib/
flutter_project:lib/
''';
    fileSystem.file(fileSystem.path.join(projectPath, '.packages'))
        ..createSync(recursive: true)
        ..writeAsStringSync(dotPackagesSrc);
  }

  setUpAll(() {
    Cache.disableLocking();
    Cache.flutterRoot = FlutterCommandRunner.defaultFlutterRoot;
    processManager = const LocalProcessManager();
    terminal = AnsiTerminal(platform: platform, stdio: Stdio());
    fileSystem = const LocalFileSystem();
    platform = const LocalPlatform();
    logger = BufferLogger(
      outputPreferences: OutputPreferences.test(),
      terminal: terminal,
    );
    analyzerSeparator = platform.isWindows ? '-' : '•';
    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);
  });

  setUp(() {
    libMain = fileSystem.file(fileSystem.path.join(projectPath, 'lib', 'main.dart'))
        ..createSync(recursive: true)
        ..writeAsStringSync(mainDartSrc);
  });

  tearDownAll(() {
    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,
      ),
      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,
      ),
      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,
      ),
      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',
      ],
      exitMessageContains: '3 issues found.',
      toolExit: true,
    );
  });

  // 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,
        ),
        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',
        ],
        exitMessageContains: '2 issues found.',
        toolExit: true,
      );
    } finally {
      if (optionsFile.existsSync()) {
        optionsFile.deleteSync();
      }
    }
  });

  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,
        ),
        arguments: <String>['analyze', '--no-pub'],
        statusTextContains: <String>[
          'Analyzing',
        ],
        exitMessageContains: '1 issue found.',
        toolExit: true,
      );
    } 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,
        ),
        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);

    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,
        ),
        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,
        ),
        arguments: <String>['analyze', '--no-pub'],
        statusTextContains: <String>['No issues found!'],
      );
    } finally {
      tryToDelete(tempDir);
    }
  });
}

void assertContains(String text, List<String> patterns) {
  if (patterns == null) {
    expect(text, isEmpty);
  } else {
    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
''';
