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