// 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', however it does not exist on disk",
        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',
        'avoid_empty_else',
        'empty_statements',
        'unused_element',
        'missing_required_param',
      ],
      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',
        'unused_element',
        'only_throw_errors',
        'missing_required_param',
      ],
      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 0.', () 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.',
    );
  });


  testWithoutContext('analyze once only fatal-warnings 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', '--no-fatal-infos', '--fatal-warnings'],
      statusTextContains: <String>[
        'warning',
        'missing_return',
      ],
      exitMessageContains: '1 issue found.',
      exitCode: 1,
    );
  });
}

void assertContains(String text, List<String> patterns) {
  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.headlineMedium,
            ),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip: 'Increment',
        child: Icon(Icons.add),
      ),
    );
  }
}
''';

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

dependencies:
  flutter:
    sdk: flutter
''';
