// 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:archive/archive.dart';
import 'package:file/memory.dart';
import 'package:flutter_tools/src/base/analyze_size.dart';
import 'package:flutter_tools/src/base/file_system.dart';
import 'package:flutter_tools/src/base/logger.dart';
import 'package:flutter_tools/src/reporting/reporting.dart';
import 'package:mockito/mockito.dart';

import '../../src/common.dart';

const String aotSizeOutput = '''[
    {
        "l": "dart:_internal",
        "c": "SubListIterable",
        "n": "[Optimized] skip",
        "s": 2400
    },
    {
        "l": "dart:_internal",
        "c": "SubListIterable",
        "n": "[Optimized] new SubListIterable.",
        "s": 3560
    },
    {
        "l": "dart:core",
        "c": "RangeError",
        "n": "[Optimized] new RangeError.range",
        "s": 3920
    },
    {
        "l": "dart:core",
        "c": "ArgumentError",
        "n": "[Stub] Allocate ArgumentError",
        "s": 4650
    }
]
''';

void main() {
  MemoryFileSystem fileSystem;
  BufferLogger logger;

  setUp(() {
    fileSystem = MemoryFileSystem.test();
    logger = BufferLogger.test();
  });

  test('matchesPattern matches only entire strings', () {
    expect(matchesPattern('', pattern: ''), isNotNull);
    expect(matchesPattern('', pattern: 'foo'), null);
    expect(matchesPattern('foo', pattern: ''), null);
    expect(matchesPattern('foo', pattern: 'foo'), isNotNull);
    expect(matchesPattern('foo', pattern: 'foobar'), null);
    expect(matchesPattern('foobar', pattern: 'foo'), null);
    expect(matchesPattern('foobar', pattern: RegExp(r'.*b.*')), isNotNull);
    expect(matchesPattern('foobar', pattern: RegExp(r'.*b')), null);
  });

  test('builds APK analysis correctly', () async {
    final SizeAnalyzer sizeAnalyzer = SizeAnalyzer(
      fileSystem: fileSystem,
      logger: logger,
      appFilenamePattern: RegExp(r'lib.*app\.so'),
      flutterUsage: MockUsage(),
    );

    final Archive archive = Archive()
      ..addFile(ArchiveFile('AndroidManifest.xml', 100,  List<int>.filled(100, 0)))
      ..addFile(ArchiveFile('META-INF/CERT.RSA', 10,  List<int>.filled(10, 0)))
      ..addFile(ArchiveFile('META-INF/CERT.SF', 10,  List<int>.filled(10, 0)))
      ..addFile(ArchiveFile('lib/arm64-v8a/libxyzzyapp.so', 50,  List<int>.filled(50, 0)))
      ..addFile(ArchiveFile('lib/arm64-v8a/libflutter.so', 50, List<int>.filled(50, 0)));

    final File apk = fileSystem.file('test.apk')
      ..writeAsBytesSync(ZipEncoder().encode(archive));
    final File aotSizeJson = fileSystem.file('test.json')
      ..createSync()
      ..writeAsStringSync(aotSizeOutput);
    final File precompilerTrace = fileSystem.file('trace.json')
      ..writeAsStringSync('{}');
    final Map<String, dynamic> result = await sizeAnalyzer.analyzeZipSizeAndAotSnapshot(
      zipFile: apk,
      aotSnapshot: aotSizeJson,
      precompilerTrace: precompilerTrace,
      kind: 'apk',
    );

    expect(result['type'], 'apk');

    final Map<String, dynamic> androidManifestMap = result['children'][0] as Map<String, dynamic>;
    expect(androidManifestMap['n'], 'AndroidManifest.xml');
    expect(androidManifestMap['value'], 6);

    final Map<String, dynamic> metaInfMap = result['children'][1] as Map<String, dynamic>;
    expect(metaInfMap['n'], 'META-INF');
    expect(metaInfMap['value'], 10);
    final Map<String, dynamic> certRsaMap = metaInfMap['children'][0] as Map<String, dynamic>;
    expect(certRsaMap['n'], 'CERT.RSA');
    expect(certRsaMap['value'], 5);
    final Map<String, dynamic> certSfMap = metaInfMap['children'][1] as Map<String, dynamic>;
    expect(certSfMap['n'], 'CERT.SF');
    expect(certSfMap['value'], 5);

    final Map<String, dynamic> libMap = result['children'][2] as Map<String, dynamic>;
    expect(libMap['n'], 'lib');
    expect(libMap['value'], 12);
    final Map<String, dynamic> arm64Map = libMap['children'][0] as Map<String, dynamic>;
    expect(arm64Map['n'], 'arm64-v8a');
    expect(arm64Map['value'], 12);
    final Map<String, dynamic> libAppMap = arm64Map['children'][0] as Map<String, dynamic>;
    expect(libAppMap['n'], 'libxyzzyapp.so (Dart AOT)');
    expect(libAppMap['value'], 6);
    expect(libAppMap['children'].length, 3);
    final Map<String, dynamic> internalMap = libAppMap['children'][0] as Map<String, dynamic>;
    final Map<String, dynamic> skipMap = internalMap['children'][0] as Map<String, dynamic>;
    expect(skipMap['n'], 'skip');
    expect(skipMap['value'], 2400);
    final Map<String, dynamic> subListIterableMap = internalMap['children'][1] as Map<String, dynamic>;
    expect(subListIterableMap['n'], 'new SubListIterable.');
    expect(subListIterableMap['value'], 3560);
    final Map<String, dynamic> coreMap = libAppMap['children'][1] as Map<String, dynamic>;
    final Map<String, dynamic> rangeErrorMap = coreMap['children'][0] as Map<String, dynamic>;
    expect(rangeErrorMap['n'], 'new RangeError.range');
    expect(rangeErrorMap['value'], 3920);
    final Map<String, dynamic> stubsMap = libAppMap['children'][2] as Map<String, dynamic>;
    final Map<String, dynamic> allocateMap = stubsMap['children'][0] as Map<String, dynamic>;
    expect(allocateMap['n'], 'Allocate ArgumentError');
    expect(allocateMap['value'], 4650);
    final Map<String, dynamic> libFlutterMap = arm64Map['children'][1] as Map<String, dynamic>;
    expect(libFlutterMap['n'], 'libflutter.so (Flutter Engine)');
    expect(libFlutterMap['value'], 6);

    expect(result['precompiler-trace'], <String, Object>{});
  });

  test('outputs summary to command line correctly', () async {
    final SizeAnalyzer sizeAnalyzer = SizeAnalyzer(
      fileSystem: fileSystem,
      logger: logger,
      appFilenamePattern: RegExp(r'lib.*app\.so'),
      flutterUsage: MockUsage(),
    );

    final Archive archive = Archive()
      ..addFile(ArchiveFile('AndroidManifest.xml', 100,  List<int>.filled(100, 0)))
      ..addFile(ArchiveFile('META-INF/CERT.RSA', 10,  List<int>.filled(10, 0)))
      ..addFile(ArchiveFile('META-INF/CERT.SF', 10,  List<int>.filled(10, 0)))
      ..addFile(ArchiveFile('lib/arm64-v8a/libxyzzyapp.so', 50,  List<int>.filled(50, 0)))
      ..addFile(ArchiveFile('lib/arm64-v8a/libflutter.so', 50, List<int>.filled(50, 0)));

    final File apk = fileSystem.file('test.apk')
      ..writeAsBytesSync(ZipEncoder().encode(archive));
    final File aotSizeJson = fileSystem.file('test.json')
      ..writeAsStringSync(aotSizeOutput);
    final File precompilerTrace = fileSystem.file('trace.json')
      ..writeAsStringSync('{}');
    await sizeAnalyzer.analyzeZipSizeAndAotSnapshot(
      zipFile: apk,
      aotSnapshot: aotSizeJson,
      precompilerTrace: precompilerTrace,
      kind: 'apk',
    );

    final List<String> stdout = logger.statusText.split('\n');
    expect(
      stdout,
      containsAll(<String>[
        'test.apk (total compressed)                                                644 B',
        '━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━',
        '  lib                                                                       12 B',
        '  Dart AOT symbols accounted decompressed size                             14 KB',
        '    dart:core/',
        '      RangeError                                                            4 KB',
      ]),
    );
  });

  test('can analyze contents of output directory', () async {
    final SizeAnalyzer sizeAnalyzer = SizeAnalyzer(
      fileSystem: fileSystem,
      logger: logger,
      appFilenamePattern: RegExp(r'lib.*app\.so'),
      flutterUsage: MockUsage(),
    );

    final Directory outputDirectory = fileSystem.directory('example/out/foo.app')
      ..createSync(recursive: true);
    outputDirectory.childFile('a.txt')
      ..createSync()
      ..writeAsStringSync('hello');
    outputDirectory.childFile('libapp.so')
      ..createSync()
      ..writeAsStringSync('goodbye');
    final File aotSizeJson = fileSystem.file('test.json')
      ..writeAsStringSync(aotSizeOutput);
    final File precompilerTrace = fileSystem.file('trace.json')
      ..writeAsStringSync('{}');

    final Map<String, Object> result = await sizeAnalyzer.analyzeAotSnapshot(
      outputDirectory: outputDirectory,
      aotSnapshot: aotSizeJson,
      precompilerTrace: precompilerTrace,
      type: 'linux',
    );

    final List<String> stdout = logger.statusText.split('\n');
    expect(
      stdout,
      containsAll(<String>[
        '  foo.app                                                                   12 B',
        '  foo.app                                                                   12 B',
        '  Dart AOT symbols accounted decompressed size                             14 KB',
        '    dart:core/',
        '      RangeError                                                            4 KB',
      ]),
    );
    expect(result['type'], 'linux');
    expect(result['precompiler-trace'], <String, Object>{});
  });
}

class MockUsage extends Mock implements Usage {}
