// 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:file/file.dart';
import 'package:file/memory.dart';
import 'package:flutter_tools/src/base/context.dart';
import 'package:flutter_tools/src/base/file_system.dart';
import 'package:flutter_tools/src/cache.dart';
import 'package:flutter_tools/src/flutter_manifest.dart';

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

void main() {
  setUpAll(() {
    Cache.flutterRoot = getFlutterRoot();
  });

  group('FlutterManifest', () {
    testUsingContext('is empty when the pubspec.yaml file is empty', () async {
      final FlutterManifest flutterManifest = FlutterManifest.createFromString('');
      expect(flutterManifest.isEmpty, true);
      expect(flutterManifest.appName, '');
      expect(flutterManifest.usesMaterialDesign, false);
      expect(flutterManifest.fontsDescriptor, isEmpty);
      expect(flutterManifest.fonts, isEmpty);
      expect(flutterManifest.assets, isEmpty);
    });

    test('has no fonts or assets when the "flutter" section is empty', () async {
      const String manifest = '''
name: test
dependencies:
  flutter:
    sdk: flutter
''';
      final FlutterManifest flutterManifest = FlutterManifest.createFromString(manifest);
      expect(flutterManifest, isNotNull);
      expect(flutterManifest.isEmpty, false);
      expect(flutterManifest.appName, 'test');
      expect(flutterManifest.usesMaterialDesign, false);
      expect(flutterManifest.fontsDescriptor, isEmpty);
      expect(flutterManifest.fonts, isEmpty);
      expect(flutterManifest.assets, isEmpty);
    });

    test('knows if material design is used', () async {
      const String manifest = '''
name: test
dependencies:
  flutter:
    sdk: flutter
flutter:
  uses-material-design: true
''';
      final FlutterManifest flutterManifest = FlutterManifest.createFromString(manifest);
      expect(flutterManifest.usesMaterialDesign, true);
    });

    test('has two assets', () async {
      const String manifest = '''
name: test
dependencies:
  flutter:
    sdk: flutter
flutter:
  uses-material-design: true
  assets:
    - a/foo
    - a/bar
''';
      final FlutterManifest flutterManifest = FlutterManifest.createFromString(manifest);
      expect(flutterManifest.assets.length, 2);
      expect(flutterManifest.assets[0], Uri.parse('a/foo'));
      expect(flutterManifest.assets[1], Uri.parse('a/bar'));
    });

    test('has one font family with one asset', () async {
      const String manifest = '''
name: test
dependencies:
  flutter:
    sdk: flutter
flutter:
  uses-material-design: true
  fonts:
    - family: foo
      fonts:
        - asset: a/bar
''';
      final FlutterManifest flutterManifest = FlutterManifest.createFromString(manifest);
      final dynamic expectedFontsDescriptor = [{'fonts': [{'asset': 'a/bar'}], 'family': 'foo'}]; // ignore: always_specify_types
      expect(flutterManifest.fontsDescriptor, expectedFontsDescriptor);
      final List<Font> fonts = flutterManifest.fonts;
      expect(fonts.length, 1);
      final Font font = fonts[0];
      final dynamic fooFontDescriptor = {'family': 'foo', 'fonts': [{'asset': 'a/bar'}]}; // ignore: always_specify_types
      expect(font.descriptor, fooFontDescriptor);
      expect(font.familyName, 'foo');
      final List<FontAsset> assets = font.fontAssets;
      expect(assets.length, 1);
      final FontAsset fontAsset = assets[0];
      expect(fontAsset.assetUri.path, 'a/bar');
      expect(fontAsset.weight, isNull);
      expect(fontAsset.style, isNull);
    });

    test('has one font family with a simple asset and one with weight', () async {
      const String manifest = '''
name: test
dependencies:
  flutter:
    sdk: flutter
flutter:
  uses-material-design: true
  fonts:
    - family: foo
      fonts:
        - asset: a/bar
        - asset: a/bar
          weight: 400
''';
      final FlutterManifest flutterManifest = FlutterManifest.createFromString(manifest);
      final dynamic expectedFontsDescriptor = [{'fonts': [{'asset': 'a/bar'}, {'weight': 400, 'asset': 'a/bar'}], 'family': 'foo'}]; // ignore: always_specify_types
      expect(flutterManifest.fontsDescriptor, expectedFontsDescriptor);
      final List<Font> fonts = flutterManifest.fonts;
      expect(fonts.length, 1);
      final Font font = fonts[0];
      final dynamic fooFontDescriptor = {'family': 'foo', 'fonts': [{'asset': 'a/bar'}, {'weight': 400, 'asset': 'a/bar'}]}; // ignore: always_specify_types
      expect(font.descriptor, fooFontDescriptor);
      expect(font.familyName, 'foo');
      final List<FontAsset> assets = font.fontAssets;
      expect(assets.length, 2);
      final FontAsset fontAsset0 = assets[0];
      expect(fontAsset0.assetUri.path, 'a/bar');
      expect(fontAsset0.weight, isNull);
      expect(fontAsset0.style, isNull);
      final FontAsset fontAsset1 = assets[1];
      expect(fontAsset1.assetUri.path, 'a/bar');
      expect(fontAsset1.weight, 400);
      expect(fontAsset1.style, isNull);
    });

    test('has one font family with a simple asset and one with weight and style', () async {
      const String manifest = '''
name: test
dependencies:
  flutter:
    sdk: flutter
flutter:
  uses-material-design: true
  fonts:
    - family: foo
      fonts:
        - asset: a/bar
        - asset: a/bar
          weight: 400
          style: italic
''';
      final FlutterManifest flutterManifest = FlutterManifest.createFromString(manifest);
      final dynamic expectedFontsDescriptor = [{'fonts': [{'asset': 'a/bar'}, {'style': 'italic', 'weight': 400, 'asset': 'a/bar'}], 'family': 'foo'}]; // ignore: always_specify_types

      expect(flutterManifest.fontsDescriptor, expectedFontsDescriptor);
      final List<Font> fonts = flutterManifest.fonts;
      expect(fonts.length, 1);
      final Font font = fonts[0];
      final dynamic fooFontDescriptor = {'family': 'foo', 'fonts': [{'asset': 'a/bar'}, {'weight': 400, 'style': 'italic', 'asset': 'a/bar'}]}; // ignore: always_specify_types
      expect(font.descriptor, fooFontDescriptor);
      expect(font.familyName, 'foo');
      final List<FontAsset> assets = font.fontAssets;
      expect(assets.length, 2);
      final FontAsset fontAsset0 = assets[0];
      expect(fontAsset0.assetUri.path, 'a/bar');
      expect(fontAsset0.weight, isNull);
      expect(fontAsset0.style, isNull);
      final FontAsset fontAsset1 = assets[1];
      expect(fontAsset1.assetUri.path, 'a/bar');
      expect(fontAsset1.weight, 400);
      expect(fontAsset1.style, 'italic');
    });

    test('has two font families, each with one simple asset and one with weight and style', () async {
      const String manifest = '''
name: test
dependencies:
  flutter:
    sdk: flutter
flutter:
  uses-material-design: true
  fonts:
    - family: foo
      fonts:
        - asset: a/bar
        - asset: a/bar
          weight: 400
          style: italic
    - family: bar
      fonts:
        - asset: a/baz
        - weight: 400
          asset: a/baz
          style: italic
''';
      final FlutterManifest flutterManifest = FlutterManifest.createFromString(manifest);
      final dynamic expectedFontsDescriptor = <dynamic>[
        {'fonts': [{'asset': 'a/bar'}, {'style': 'italic', 'weight': 400, 'asset': 'a/bar'}], 'family': 'foo'}, // ignore: always_specify_types
        {'fonts': [{'asset': 'a/baz'}, {'style': 'italic', 'weight': 400, 'asset': 'a/baz'}], 'family': 'bar'}, // ignore: always_specify_types
      ];
      expect(flutterManifest.fontsDescriptor, expectedFontsDescriptor);
      final List<Font> fonts = flutterManifest.fonts;
      expect(fonts.length, 2);

      final Font fooFont = fonts[0];
      final dynamic fooFontDescriptor = {'family': 'foo', 'fonts': [{'asset': 'a/bar'}, {'weight': 400, 'style': 'italic', 'asset': 'a/bar'}]}; // ignore: always_specify_types
      expect(fooFont.descriptor, fooFontDescriptor);
      expect(fooFont.familyName, 'foo');
      final List<FontAsset> fooAassets = fooFont.fontAssets;
      expect(fooAassets.length, 2);
      final FontAsset fooFontAsset0 = fooAassets[0];
      expect(fooFontAsset0.assetUri.path, 'a/bar');
      expect(fooFontAsset0.weight, isNull);
      expect(fooFontAsset0.style, isNull);
      final FontAsset fooFontAsset1 = fooAassets[1];
      expect(fooFontAsset1.assetUri.path, 'a/bar');
      expect(fooFontAsset1.weight, 400);
      expect(fooFontAsset1.style, 'italic');

      final Font barFont = fonts[1];
      const String fontDescriptor = '{family: bar, fonts: [{asset: a/baz}, {weight: 400, style: italic, asset: a/baz}]}'; // ignore: always_specify_types
      expect(barFont.descriptor.toString(), fontDescriptor);
      expect(barFont.familyName, 'bar');
      final List<FontAsset> barAssets = barFont.fontAssets;
      expect(barAssets.length, 2);
      final FontAsset barFontAsset0 = barAssets[0];
      expect(barFontAsset0.assetUri.path, 'a/baz');
      expect(barFontAsset0.weight, isNull);
      expect(barFontAsset0.style, isNull);
      final FontAsset barFontAsset1 = barAssets[1];
      expect(barFontAsset1.assetUri.path, 'a/baz');
      expect(barFontAsset1.weight, 400);
      expect(barFontAsset1.style, 'italic');
    });

    testUsingContext('has only one of two font families when one declaration is missing the "family" option', () async {
      const String manifest = '''
name: test
dependencies:
  flutter:
    sdk: flutter
flutter:
  uses-material-design: true
  fonts:
    - family: foo
      fonts:
        - asset: a/bar
        - asset: a/bar
          weight: 400
          style: italic
    - fonts:
        - asset: a/baz
        - asset: a/baz
          weight: 400
          style: italic
''';
      final FlutterManifest flutterManifest = FlutterManifest.createFromString(manifest);

      final dynamic expectedFontsDescriptor = [{'fonts': [{'asset': 'a/bar'}, {'style': 'italic', 'weight': 400, 'asset': 'a/bar'}], 'family': 'foo'}]; // ignore: always_specify_types
      expect(flutterManifest.fontsDescriptor, expectedFontsDescriptor);
      final List<Font> fonts = flutterManifest.fonts;
      expect(fonts.length, 1);
      final Font fooFont = fonts[0];
      final dynamic fooFontDescriptor = {'family': 'foo', 'fonts': [{'asset': 'a/bar'}, {'weight': 400, 'style': 'italic', 'asset': 'a/bar'}]}; // ignore: always_specify_types
      expect(fooFont.descriptor, fooFontDescriptor);
      expect(fooFont.familyName, 'foo');
      final List<FontAsset> fooAassets = fooFont.fontAssets;
      expect(fooAassets.length, 2);
      final FontAsset fooFontAsset0 = fooAassets[0];
      expect(fooFontAsset0.assetUri.path, 'a/bar');
      expect(fooFontAsset0.weight, isNull);
      expect(fooFontAsset0.style, isNull);
      final FontAsset fooFontAsset1 = fooAassets[1];
      expect(fooFontAsset1.assetUri.path, 'a/bar');
      expect(fooFontAsset1.weight, 400);
      expect(fooFontAsset1.style, 'italic');
    });

    testUsingContext('has only one of two font families when one declaration is missing the "fonts" option', () async {
      const String manifest = '''
name: test
dependencies:
  flutter:
    sdk: flutter
flutter:
  uses-material-design: true
  fonts:
    - family: foo
      fonts:
        - asset: a/bar
        - asset: a/bar
          weight: 400
          style: italic
    - family: bar
''';
      final FlutterManifest flutterManifest = FlutterManifest.createFromString(manifest);
      final dynamic expectedFontsDescriptor = [{'fonts': [{'asset': 'a/bar'}, {'style': 'italic', 'weight': 400, 'asset': 'a/bar'}], 'family': 'foo'}]; // ignore: always_specify_types
      expect(flutterManifest.fontsDescriptor, expectedFontsDescriptor);
      final List<Font> fonts = flutterManifest.fonts;
      expect(fonts.length, 1);
      final Font fooFont = fonts[0];
      final dynamic fooFontDescriptor = {'family': 'foo', 'fonts': [{'asset': 'a/bar'}, {'weight': 400, 'style': 'italic', 'asset': 'a/bar'}]}; // ignore: always_specify_types
      expect(fooFont.descriptor, fooFontDescriptor);
      expect(fooFont.familyName, 'foo');
      final List<FontAsset> fooAassets = fooFont.fontAssets;
      expect(fooAassets.length, 2);
      final FontAsset fooFontAsset0 = fooAassets[0];
      expect(fooFontAsset0.assetUri.path, 'a/bar');
      expect(fooFontAsset0.weight, isNull);
      expect(fooFontAsset0.style, isNull);
      final FontAsset fooFontAsset1 = fooAassets[1];
      expect(fooFontAsset1.assetUri.path, 'a/bar');
      expect(fooFontAsset1.weight, 400);
      expect(fooFontAsset1.style, 'italic');
    });

    testUsingContext('has no font family when declaration is missing the "asset" option', () async {
      const String manifest = '''
name: test
dependencies:
  flutter:
    sdk: flutter
flutter:
  uses-material-design: true
  fonts:
    - family: foo
      fonts:
        - weight: 400
''';
      final FlutterManifest flutterManifest = FlutterManifest.createFromString(manifest);

      expect(flutterManifest.fontsDescriptor, <dynamic>[]);
      final List<Font> fonts = flutterManifest.fonts;
      expect(fonts.length, 0);
    });

    test('allows a blank flutter section', () async {
      const String manifest = '''
name: test
dependencies:
  flutter:
    sdk: flutter
flutter:
''';
      final FlutterManifest flutterManifest = FlutterManifest.createFromString(manifest);
      expect(flutterManifest.isEmpty, false);
      expect(flutterManifest.isModule, false);
      expect(flutterManifest.isPlugin, false);
      expect(flutterManifest.androidPackage, null);
      expect(flutterManifest.usesAndroidX, false);
    });

    test('allows a module declaration', () async {
      const String manifest = '''
name: test
flutter:
  module:
    androidPackage: com.example
    androidX: true
''';
      final FlutterManifest flutterManifest = FlutterManifest.createFromString(manifest);
      expect(flutterManifest.isModule, true);
      expect(flutterManifest.androidPackage, 'com.example');
      expect(flutterManifest.usesAndroidX, true);
    });

    test('allows a legacy plugin declaration', () async {
      const String manifest = '''
name: test
flutter:
  plugin:
    androidPackage: com.example
''';
      final FlutterManifest flutterManifest = FlutterManifest.createFromString(manifest);
      expect(flutterManifest.isPlugin, true);
      expect(flutterManifest.androidPackage, 'com.example');
    });

    test('allows a multi-plat plugin declaration with android only', () async {
      const String manifest = '''
name: test
flutter:
    plugin:
      platforms:
        android:
          package: com.example
          pluginClass: TestPlugin
''';
      final FlutterManifest flutterManifest = FlutterManifest.createFromString(manifest);
      expect(flutterManifest.isPlugin, true);
      expect(flutterManifest.androidPackage, 'com.example');
    });

    test('allows a multi-plat plugin declaration with ios only', () async {
      const String manifest = '''
name: test
flutter:
    plugin:
      platforms:
        ios:
          pluginClass: HelloPlugin
''';
      final FlutterManifest flutterManifest = FlutterManifest.createFromString(manifest);
      expect(flutterManifest.isPlugin, true);
      expect(flutterManifest.androidPackage, isNull);
    });

    testUsingContext('handles an invalid plugin declaration', () async {
      const String manifest = '''
name: test
flutter:
    plugin:
''';
      final FlutterManifest flutterManifest = FlutterManifest.createFromString(manifest);
      expect(flutterManifest, null);
      expect(testLogger.errorText, contains('Expected "plugin" to be an object, but got null'));
    });


    Future<void> checkManifestVersion({
      String manifest,
      String expectedAppVersion,
      String expectedBuildName,
      String expectedBuildNumber,
    }) async {
      final FlutterManifest flutterManifest = FlutterManifest.createFromString(manifest);
      expect(flutterManifest.appVersion, expectedAppVersion);
      expect(flutterManifest.buildName, expectedBuildName);
      expect(flutterManifest.buildNumber, expectedBuildNumber);
    }

    test('parses major.minor.patch+build version clause 1', () async {
      const String manifest = '''
name: test
version: 1.0.0+2
dependencies:
  flutter:
    sdk: flutter
flutter:
''';
      await checkManifestVersion(
        manifest: manifest,
        expectedAppVersion: '1.0.0+2',
        expectedBuildName: '1.0.0',
        expectedBuildNumber: '2',
      );
    });

    test('parses major.minor.patch with no build version', () async {
      const String manifest = '''
name: test
version: 0.0.1
dependencies:
  flutter:
    sdk: flutter
flutter:
''';
      await checkManifestVersion(
        manifest: manifest,
        expectedAppVersion: '0.0.1',
        expectedBuildName: '0.0.1',
        expectedBuildNumber: null,
      );
    });

    test('parses major.minor.patch+build version clause 2', () async {
      const String manifest = '''
name: test
version: 1.0.0-beta+exp.sha.5114f85
dependencies:
  flutter:
    sdk: flutter
flutter:
''';
      await checkManifestVersion(
        manifest: manifest,
        expectedAppVersion: '1.0.0-beta+exp.sha.5114f85',
        expectedBuildName: '1.0.0-beta',
        expectedBuildNumber: 'exp.sha.5114f85',
      );
    });

    test('parses major.minor+build version clause', () async {
      const String manifest = '''
name: test
version: 1.0+2
dependencies:
  flutter:
    sdk: flutter
flutter:
''';
      await checkManifestVersion(
        manifest: manifest,
        expectedAppVersion: '1.0+2',
        expectedBuildName: '1.0',
        expectedBuildNumber: '2',
      );
    });

    test('parses empty version clause', () async {
      const String manifest = '''
name: test
version:
dependencies:
  flutter:
    sdk: flutter
flutter:
''';
      await checkManifestVersion(
        manifest: manifest,
        expectedAppVersion: null,
        expectedBuildName: null,
        expectedBuildNumber: null,
      );
    });

    test('parses no version clause', () async {
      const String manifest = '''
name: test
dependencies:
  flutter:
    sdk: flutter
flutter:
''';
      await checkManifestVersion(
        manifest: manifest,
        expectedAppVersion: null,
        expectedBuildName: null,
        expectedBuildNumber: null,
      );
    });

    // Regression test for https://github.com/flutter/flutter/issues/31764
    testUsingContext('Returns proper error when font detail is malformed', () async {
      const String manifest = '''
name: test
dependencies:
  flutter:
    sdk: flutter
flutter:
  fonts:
    - family: foo
      fonts:
        -asset: a/bar
''';
      final FlutterManifest flutterManifest = FlutterManifest.createFromString(manifest);

      expect(flutterManifest, null);
      expect(testLogger.errorText, contains('Expected "fonts" to either be null or a list.'));
    });

    testUsingContext('Returns proper error when font detail is not a list of maps', () async {
      const String manifest = '''
name: test
dependencies:
  flutter:
    sdk: flutter
flutter:
  fonts:
    - family: foo
      fonts:
        - asset
''';
      final FlutterManifest flutterManifest = FlutterManifest.createFromString(manifest);

      expect(flutterManifest, null);
      expect(testLogger.errorText, contains('Expected "fonts" to be a list of maps.'));
    });

    testUsingContext('Returns proper error when font is a map instead of a list', () async {
      const String manifest = '''
name: test
dependencies:
  flutter:
    sdk: flutter
flutter:
  fonts:
    family: foo
    fonts:
      -asset: a/bar
''';
      final FlutterManifest flutterManifest = FlutterManifest.createFromString(manifest);

      expect(flutterManifest, null);
      expect(testLogger.errorText, contains('Expected "fonts" to be a list'));
    });

    testUsingContext('Returns proper error when second font family is invalid', () async {
      const String manifest = '''
name: test
dependencies:
  flutter:
    sdk: flutter
flutter:
  uses-material-design: true
  fonts:
    - family: foo
      fonts:
        - asset: a/bar
    - string
''';
      final FlutterManifest flutterManifest = FlutterManifest.createFromString(manifest);
      expect(flutterManifest, null);
      expect(testLogger.errorText, contains('Expected a map.'));
    });

    testUsingContext('Does not crash on empty entry', () async {
      const String manifest = '''
name: test
dependencies:
  flutter:
    sdk: flutter
flutter:
  uses-material-design: true
  assets:
    - lib/gallery/example_code.dart
    -
''';
      final FlutterManifest flutterManifest = FlutterManifest.createFromString(manifest);
      final List<Uri> assets = flutterManifest.assets;

      expect(testLogger.errorText, contains('Asset manifest contains a null or empty uri.'));
      expect(assets.length, 1);
    });

    testUsingContext('Special characters in asset URIs', () async {
      const String manifest = '''
name: test
dependencies:
  flutter:
    sdk: flutter
flutter:
  uses-material-design: true
  assets:
    - lib/gallery/abc#xyz
    - lib/gallery/abc?xyz
    - lib/gallery/aaa bbb
''';
      final FlutterManifest flutterManifest = FlutterManifest.createFromString(manifest);
      final List<Uri> assets = flutterManifest.assets;

      expect(assets.length, 3);
      expect(assets[0].path, 'lib/gallery/abc%23xyz');
      expect(assets[1].path, 'lib/gallery/abc%3Fxyz');
      expect(assets[2].path, 'lib/gallery/aaa%20bbb');
    });

    testUsingContext('Returns proper error when flutter is a list instead of a map', () async {
      const String manifest = '''
name: test
dependencies:
  flutter:
    sdk: flutter
flutter:
  - uses-material-design: true
''';
      final FlutterManifest flutterManifest = FlutterManifest.createFromString(manifest);

      expect(flutterManifest, null);
      expect(testLogger.errorText, contains('Expected "flutter" section to be an object or null, but got [{uses-material-design: true}].'));
    });
  });

  group('FlutterManifest with MemoryFileSystem', () {
    Future<void> assertSchemaIsReadable() async {
      const String manifest = '''
name: test
dependencies:
  flutter:
    sdk: flutter
flutter:
''';

      final FlutterManifest flutterManifest = FlutterManifest.createFromString(manifest);
      expect(flutterManifest.isEmpty, false);
    }

    void testUsingContextAndFs(
      String description,
      FileSystem filesystem,
      dynamic testMethod(),
    ) {
      testUsingContext(
        description,
        () async {
          writeEmptySchemaFile(filesystem);
          testMethod();
        },
        overrides: <Type, Generator>{
          FileSystem: () => filesystem,
          ProcessManager: () => FakeProcessManager.any(),
        },
      );
    }

    testUsingContext('Validate manifest on original fs', () {
      assertSchemaIsReadable();
    });

    testUsingContextAndFs(
      'Validate manifest on Posix FS',
      MemoryFileSystem(style: FileSystemStyle.posix),
      () {
        assertSchemaIsReadable();
      },
    );

    testUsingContextAndFs(
      'Validate manifest on Windows FS',
      MemoryFileSystem(style: FileSystemStyle.windows),
      () {
        assertSchemaIsReadable();
      },
    );

  });
}
