// 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/file_system.dart';
import 'package:flutter_tools/src/base/io.dart';
import '../src/common.dart';
import 'test_utils.dart';

final String analyzerSeparator = platform.isWindows ? '-' : '•';

void main() {
  late Directory tempDir;
  late String projectPath;
  late File libMain;
  late File errorFile;

  Future<void> runCommand({
    List<String> arguments = const <String>[],
    List<String> statusTextContains = const <String>[],
    List<String> errorTextContains = const <String>[],
    String exitMessageContains = '',
    int exitCode = 0,
  }) async {
    final ProcessResult result = await processManager.run(<String>[
      fileSystem.path.join(getFlutterRoot(), 'bin', 'flutter'),
      '--no-color',
      ...arguments,
    ], workingDirectory: projectPath);
    printOnFailure('Output of flutter ${arguments.join(" ")}');
    printOnFailure(result.stdout.toString());
    printOnFailure(result.stderr.toString());
    expect(result.exitCode, exitCode, reason: 'Expected to exit with non-zero exit code.');
    assertContains(result.stdout.toString(), statusTextContains);
    assertContains(result.stdout.toString(), errorTextContains);
    expect(result.stderr, contains(exitMessageContains));
  }

  void _createDotPackages(String projectPath, [bool nullSafe = false]) {
    final StringBuffer flutterRootUri = StringBuffer('file://');
    final String canonicalizedFlutterRootPath = fileSystem.path.canonicalize(getFlutterRoot());
    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.12"
    },
    {
      "name": "sky_engine",
      "rootUri": "$flutterRootUri/bin/cache/pkg/sky_engine",
      "packageUri": "lib/",
      "languageVersion": "2.12"
    },
    {
      "name": "flutter_project",
      "rootUri": "../",
      "packageUri": "lib/",
      "languageVersion": "${nullSafe ? "2.12" : "2.7"}"
    }
  ]
}
''';

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

  setUp(() {
    tempDir = fileSystem.systemTempDirectory.createTempSync('flutter_analyze_once_test_1.').absolute;
    projectPath = fileSystem.path.join(tempDir.path, 'flutter_project');
    final String projectWithErrors = fileSystem.path.join(tempDir.path, 'flutter_project_errors');
    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);
    errorFile = fileSystem.file(fileSystem.path.join(projectWithErrors, 'other', 'error.dart'))
      ..createSync(recursive: true)
      ..writeAsStringSync(r"""import 'package:flutter/material.dart""");
  });

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

  // Analyze in the current directory - no arguments
  testWithoutContext('working directory', () async {
    await runCommand(
      arguments: <String>['analyze', '--no-pub'],
      statusTextContains: <String>['No issues found!'],
    );
  });

  testWithoutContext('passing one file works', () async {
    await runCommand(
      arguments: <String>['analyze', '--no-pub', libMain.path],
      statusTextContains: <String>['No issues found!']
    );
  });

  testWithoutContext('passing one file with errors are detected', () async {
    await runCommand(
        arguments: <String>['analyze', '--no-pub', errorFile.path],
        statusTextContains: <String>[
          'Analyzing error.dart',
          "error $analyzerSeparator Target of URI doesn't exist",
          "error $analyzerSeparator Expected to find ';'",
          'error $analyzerSeparator Unterminated string literal'
        ],
        exitMessageContains: '3 issues found',
        exitCode: 1
    );
  });

  testWithoutContext('passing more than one file with errors', () async {
    await runCommand(
        arguments: <String>['analyze', '--no-pub', libMain.path, errorFile.path],
        statusTextContains: <String>[
          'Analyzing 2 items',
          "error $analyzerSeparator Target of URI doesn't exist",
          "error $analyzerSeparator Expected to find ';'",
          'error $analyzerSeparator Unterminated string literal'
        ],
        exitMessageContains: '3 issues found',
        exitCode: 1
    );
  });

  testWithoutContext('passing more than one file success', () async {
    final File secondFile = fileSystem.file(fileSystem.path.join(projectPath, 'lib', 'second.dart'))
      ..createSync(recursive: true)
      ..writeAsStringSync('');
    await runCommand(
        arguments: <String>['analyze', '--no-pub', libMain.path, secondFile.path],
        statusTextContains: <String>['No issues found!']
    );
  });

  testWithoutContext('mixing directory and files success', () async {
    await runCommand(
        arguments: <String>['analyze', '--no-pub', libMain.path, projectPath],
        statusTextContains: <String>['No issues found!']
    );
  });

  testWithoutContext('file not found', () async {
    await runCommand(
        arguments: <String>['analyze', '--no-pub', 'not_found.abc'],
        exitMessageContains: "not_found.abc' does not exist",
        exitCode: 1
    );
  });

  // Analyze in the current directory - no arguments
  testWithoutContext('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(
      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.',
      exitCode: 1,
    );
  });

  // Analyze in the current directory - no arguments
  testWithoutContext('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'));
      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(
      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.',
      exitCode: 1,
    );
  });

  testWithoutContext('analyze once no duplicate issues', () async {
    final File foo = fileSystem.file(fileSystem.path.join(projectPath, 'foo.dart'));
    foo.writeAsStringSync('''
import 'bar.dart';

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

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

void bar() {
}
''');

    // Analyze in the current directory - no arguments
    await runCommand(
      arguments: <String>['analyze', '--no-pub'],
      statusTextContains: <String>[
        'Analyzing',
      ],
      exitMessageContains: '1 issue found.',
      exitCode: 1
    );
  });

  testWithoutContext('analyze once returns no issues when source is error-free', () async {
    const String contents = '''
StringBuffer bar = StringBuffer('baz');
''';

    fileSystem.directory(projectPath).childFile('main.dart').writeAsStringSync(contents);
    await runCommand(
      arguments: <String>['analyze', '--no-pub'],
      statusTextContains: <String>['No issues found!'],
    );
  });

  testWithoutContext('analyze once returns no issues for todo comments', () async {
    const String contents = '''
// TODO(foobar):
StringBuffer bar = StringBuffer('baz');
''';

    fileSystem.directory(projectPath).childFile('main.dart').writeAsStringSync(contents);
    await runCommand(
      arguments: <String>['analyze', '--no-pub'],
      statusTextContains: <String>['No issues found!'],
    );
  });

  testWithoutContext('analyze once with default options has info issue finally exit code 1.', () async {
    const String infoSourceCode = '''
int analyze() {}
''';

    fileSystem.directory(projectPath).childFile('main.dart').writeAsStringSync(infoSourceCode);
    await runCommand(
      arguments: <String>['analyze', '--no-pub'],
      statusTextContains: <String>[
        'info',
        'missing_return',
      ],
      exitMessageContains: '1 issue found.',
      exitCode: 1,
    );
  });

  testWithoutContext('analyze once with no-fatal-infos has info issue finally exit code 0.', () async {
    const String infoSourceCode = '''
int analyze() {}
''';

    fileSystem.directory(projectPath).childFile('main.dart').writeAsStringSync(infoSourceCode);
    await runCommand(
      arguments: <String>['analyze', '--no-pub', '--no-fatal-infos'],
      statusTextContains: <String>[
        'info',
        'missing_return',
      ],
      exitMessageContains: '1 issue found.',
    );
  });

  testWithoutContext('analyze once only fatal-warnings has info issue finally exit code 0.', () async {
    const String infoSourceCode = '''
int analyze() {}
''';

    fileSystem.directory(projectPath).childFile('main.dart').writeAsStringSync(infoSourceCode);
    await runCommand(
      arguments: <String>['analyze', '--no-pub', '--fatal-warnings', '--no-fatal-infos'],
      statusTextContains: <String>[
        'info',
        'missing_return',
      ],
      exitMessageContains: '1 issue found.',
    );
  });

  testWithoutContext('analyze once only fatal-infos has warning issue finally exit code 1.', () async {
    const String warningSourceCode = '''
int analyze() {}
''';

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

    fileSystem.directory(projectPath).childFile('main.dart').writeAsStringSync(warningSourceCode);
    await runCommand(
      arguments: <String>['analyze','--no-pub', '--fatal-infos', '--no-fatal-warnings'],
      statusTextContains: <String>[
        'warning',
        'missing_return',
      ],
      exitMessageContains: '1 issue found.',
      exitCode: 1,
    );
  });
}

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