// 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.

// @dart = 2.8

import 'package:file/file.dart';
import 'package:file/memory.dart';
import 'package:flutter_tools/src/base/io.dart';
import 'package:flutter_tools/src/base/logger.dart';
import 'package:flutter_tools/src/devfs.dart';
import 'package:flutter_tools/src/project.dart';
import 'package:flutter_tools/src/reporting/reporting.dart';

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

const String _kShortURL = 'https://www.example.com/short';

void main() {
  BufferLogger logger;
  FileSystem fs;
  setUp(() {
    logger = BufferLogger.test();
    fs = MemoryFileSystem.test();
  });

  group('GitHub template creator', () {
    testWithoutContext('similar issues URL', () {
      expect(
        GitHubTemplateCreator.toolCrashSimilarIssuesURL('this is a 100% error'),
        'https://github.com/flutter/flutter/issues?q=is%3Aissue+this+is+a+100%25+error',
      );
    });

    group('sanitized error message', () {
      testWithoutContext('ProcessException', () {
        expect(
          GitHubTemplateCreator.sanitizedCrashException(
            const ProcessException('cd', <String>['path/to/something'])
          ),
          'ProcessException:  Command: cd, OS error code: 0',
        );
        expect(
          GitHubTemplateCreator.sanitizedCrashException(
            const ProcessException('cd', <String>['path/to/something'], 'message')
          ),
          'ProcessException: message Command: cd, OS error code: 0',
        );
        expect(
          GitHubTemplateCreator.sanitizedCrashException(
            const ProcessException('cd', <String>['path/to/something'], 'message', -19)
          ),
          'ProcessException: message Command: cd, OS error code: -19',
        );
      });

      testWithoutContext('FileSystemException', () {
        expect(
          GitHubTemplateCreator.sanitizedCrashException(
            const FileSystemException('delete failed', 'path/to/something')
          ),
          'FileSystemException: delete failed, null',
        );
        expect(
          GitHubTemplateCreator.sanitizedCrashException(
            const FileSystemException('delete failed', 'path/to/something', OSError('message', -19))
          ),
          'FileSystemException: delete failed, OS Error: message, errno = -19',
        );
      });

      testWithoutContext('SocketException', () {
        expect(
          GitHubTemplateCreator.sanitizedCrashException(
            SocketException(
              'message',
              osError: const OSError('message', -19),
              address: InternetAddress.anyIPv6,
              port: 2000
            )
          ),
          'SocketException: message, OS Error: message, errno = -19',
        );
      });

      testWithoutContext('DevFSException', () {
        final StackTrace stackTrace = StackTrace.fromString('''
#0      _File.open.<anonymous closure> (dart:io/file_impl.dart:366:9)
#1      _rootRunUnary (dart:async/zone.dart:1141:38)''');
        expect(
          GitHubTemplateCreator.sanitizedCrashException(
            DevFSException('message', ArgumentError('argument error message'), stackTrace)
          ),
          'DevFSException: message',
        );
      });

      testWithoutContext('ArgumentError', () {
        expect(
          GitHubTemplateCreator.sanitizedCrashException(
            ArgumentError('argument error message')
          ),
          'ArgumentError: Invalid argument(s): argument error message',
        );
      });

      testWithoutContext('Error', () {
        expect(
          GitHubTemplateCreator.sanitizedCrashException(
            FakeError()
          ),
          'FakeError: (#0      _File.open.<anonymous closure> (dart:io/file_impl.dart:366:9))',
        );
      });

      testWithoutContext('String', () {
        expect(
          GitHubTemplateCreator.sanitizedCrashException(
            'May have non-tool-internal info, very long string, 0b8abb4724aa590dd0f429683339b'
              '24aa590dd0f429683339b1e045a1594d0b8abb4724aa590dd0f429683339b1e045a1594d0b8abb'
              '24aa590dd0f429683339b1e045a1594d0b8abb4724aa590dd0f429683339b1e045a1594d0b8abb'
              '24aa590dd0f429683339b1e045a1594d0b8abb4724aa590dd0f429683339b1e045a1594d0b8abb'
              '24aa590dd0f429683339b1e045a1594d0b8abb4724aa590dd0f429683339b1e045a1594d0b8abb'
              '24aa590dd0f429683339b1e045a1594d0b8abb4724aa590dd0f429683339b1e045a1594d0b8abb'
              '24aa590dd0f429683339b1e045a1594d0b8abb4724aa590dd0f429683339b1e045a1594d0b8abb'
              '24aa590dd0f429683339b1e045a1594d0b8abb4724aa590dd0f429683339b1e045a1594d0b8abb'
              '24aa590dd0f429683339b1e045a1594d0b8abb4724aa590dd0f429683339b1e045a1594d0b8abb'
              '24aa590dd0f429683339b1e045a1594d0b8abb4724aa590dd0f429683339b1e045a1594d0b8abb'
              '24aa590dd0f429683339b1e045a1594d0b8abb4724aa590dd0f429683339b1e045a1594d0b8abb'
              '24aa590dd0f429683339b1e045a1594d0b8abb4724aa590dd0f429683339b1e045a1594d0b8abb'
              '24aa590dd0f429683339b1e045a1594d0b8abb4724aa590dd0f429683339b1e045a1594d0b8abb'
          ),
          'String: <1,016 characters>',
        );
      });

      testWithoutContext('Exception', () {
        expect(
          GitHubTemplateCreator.sanitizedCrashException(
            Exception('May have non-tool-internal info')
          ),
          '_Exception',
        );
      });
    });

    group('new issue template URL', () {
      StackTrace stackTrace;
      Error error;
      const String command = 'flutter test';
      const String doctorText = ' [✓] Flutter (Channel report';

      setUp(() async {
        stackTrace = StackTrace.fromString('trace');
        error = ArgumentError('argument error message');
      });

      testUsingContext('shortened', () async {
        final GitHubTemplateCreator creator = GitHubTemplateCreator(
          fileSystem: fs,
          logger: logger,
          client: FakeHttpClient.list(<FakeRequest>[
            FakeRequest(Uri.parse('https://git.io'), method: HttpMethod.post, response: const FakeResponse(
              statusCode: 201,
              headers: <String, List<String>>{
                HttpHeaders.locationHeader: <String>[_kShortURL],
              }
            ))
          ]),
          flutterProjectFactory: FlutterProjectFactory(
            fileSystem: fs,
            logger: logger,
          ),
        );
        expect(
            await creator.toolCrashIssueTemplateGitHubURL(command, error, stackTrace, doctorText),
            _kShortURL
        );
      }, overrides: <Type, Generator>{
        FileSystem: () => MemoryFileSystem.test(),
        ProcessManager: () => FakeProcessManager.any(),
      });

      testUsingContext('with network failure', () async {
        final GitHubTemplateCreator creator = GitHubTemplateCreator(
          fileSystem: fs,
          logger: logger,
          client: FakeHttpClient.list(<FakeRequest>[
            FakeRequest(Uri.parse('https://git.io'), method: HttpMethod.post, response: const FakeResponse(
              statusCode: 500,
            ))
          ]),
          flutterProjectFactory: FlutterProjectFactory(
            fileSystem: fs,
            logger: logger,
          ),
        );
        expect(
            await creator.toolCrashIssueTemplateGitHubURL(command, error, stackTrace, doctorText),
          'https://github.com/flutter/flutter/issues/new?title=%5Btool_crash%5D+ArgumentError%3A+'
            'Invalid+argument%28s%29%3A+argument+error+message&body=%23%23+Command%0A%60%60%60%0A'
            'flutter+test%0A%60%60%60%0A%0A%23%23+Steps+to+Reproduce%0A1.+...%0A2.+...%0A3.+...%0'
            'A%0A%23%23+Logs%0AArgumentError%3A+Invalid+argument%28s%29%3A+argument+error+message'
            '%0A%60%60%60%0Atrace%0A%60%60%60%0A%60%60%60%0A+%5B%E2%9C%93%5D+Flutter+%28Channel+r'
            'eport%0A%60%60%60%0A%0A%23%23+Flutter+Application+Metadata%0ANo+pubspec+in+working+d'
            'irectory.%0A&labels=tool%2Csevere%3A+crash'
        );
        expect(logger.traceText, contains('Failed to shorten GitHub template URL'));
      }, overrides: <Type, Generator>{
        FileSystem: () => MemoryFileSystem.test(),
        ProcessManager: () => FakeProcessManager.any(),
      });

      testUsingContext('app metadata', () async {
        final GitHubTemplateCreator creator = GitHubTemplateCreator(
          fileSystem: fs,
          logger: logger,
          client: FakeHttpClient.any(),
          flutterProjectFactory: FlutterProjectFactory(
            fileSystem: fs,
            logger: logger,
          ),
        );
        final Directory projectDirectory = fs.currentDirectory;

        projectDirectory
            .childFile('pubspec.yaml')
            .writeAsStringSync('''
name: failing_app
version: 2.0.1+100
flutter:
  uses-material-design: true
  module:
    androidX: true
    androidPackage: com.example.failing.android
    iosBundleIdentifier: com.example.failing.ios
''');

        final File pluginsFile = projectDirectory.childFile('.flutter-plugins');
        pluginsFile
            .writeAsStringSync('''
camera=/fake/pub.dartlang.org/camera-0.5.7+2/
device_info=/fake/pub.dartlang.org/pub.dartlang.org/device_info-0.4.1+4/
        ''');

        final File metadataFile = projectDirectory.childFile('.metadata');
        metadataFile
          .writeAsStringSync('''
version:
  revision: 0b8abb4724aa590dd0f429683339b1e045a1594d
  channel: stable

project_type: app
        ''');

        final String actualURL = await creator.toolCrashIssueTemplateGitHubURL(command, error, stackTrace, doctorText);
        final String actualBody = Uri.parse(actualURL).queryParameters['body'];
        const String expectedBody = '''
## Command
```
flutter test
```

## Steps to Reproduce
1. ...
2. ...
3. ...

## Logs
ArgumentError: Invalid argument(s): argument error message
```
trace
```
```
 [✓] Flutter (Channel report
```

## Flutter Application Metadata
**Type**: app
**Version**: 2.0.1+100
**Material**: true
**Android X**: true
**Module**: true
**Plugin**: false
**Android package**: com.example.failing.android
**iOS bundle identifier**: com.example.failing.ios
**Creation channel**: stable
**Creation framework version**: 0b8abb4724aa590dd0f429683339b1e045a1594d
### Plugins
camera-0.5.7+2
device_info-0.4.1+4

''';

        expect(actualBody, expectedBody);
      }, overrides: <Type, Generator>{
        FileSystem: () => fs,
        ProcessManager: () => FakeProcessManager.any(),
      });
    });
  });
}

class FakeError extends Error {
  @override
  StackTrace get stackTrace => StackTrace.fromString('''
#0      _File.open.<anonymous closure> (dart:io/file_impl.dart:366:9)
#1      _rootRunUnary (dart:async/zone.dart:1141:38)''');
}
