// Copyright 2017 The Chromium 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 'dart:convert';
import 'dart:typed_data';

import 'package:flutter/foundation.dart';
import 'package:flutter/painting.dart';
import 'package:flutter/services.dart';
import 'package:flutter_test/flutter_test.dart';


class TestAssetBundle extends CachingAssetBundle {
  TestAssetBundle(this._assetBundleMap);

  Map<String, List<String>> _assetBundleMap;

  Map<String, int> loadCallCount = <String, int>{};

  String get _assetBundleContents {
    return json.encode(_assetBundleMap);
  }

  @override
  Future<ByteData> load(String key) async {
    if (key == 'AssetManifest.json')
      return ByteData.view(Uint8List.fromList(
          const Utf8Encoder().convert(_assetBundleContents)).buffer);

    loadCallCount[key] = loadCallCount[key] ?? 0 + 1;
    if (key == 'one')
      return ByteData(1)
        ..setInt8(0, 49);
    throw FlutterError('key not found');
  }
}

void main() {
  group('1.0 scale device tests', () {
    void _buildAndTestWithOneAsset(String mainAssetPath) {
      final Map<String, List<String>> assetBundleMap = <String, List<String>>{};

      assetBundleMap[mainAssetPath] = <String>[];

      final AssetImage assetImage = AssetImage(
          mainAssetPath,
          bundle: TestAssetBundle(assetBundleMap));
      const ImageConfiguration configuration = ImageConfiguration();

      assetImage.obtainKey(configuration)
        .then(expectAsync1((AssetBundleImageKey bundleKey) {
          expect(bundleKey.name, mainAssetPath);
          expect(bundleKey.scale, 1.0);
        }));
    }

    test('When asset is main variant check scale is 1.0', () {
      _buildAndTestWithOneAsset('assets/normalFolder/normalFile.png');
    });

    test('When asset path and key are the same string even though it could be took as a 3.0x variant', () async {
      _buildAndTestWithOneAsset('assets/parentFolder/3.0x/normalFile.png');
    });

    test('When asset path contains variant identifier as part of parent folder name scale is 1.0', () {
      _buildAndTestWithOneAsset('assets/parentFolder/__3.0x__/leafFolder/normalFile.png');
    });

    test('When asset path contains variant identifier as part of leaf folder name scale is 1.0', () {
      _buildAndTestWithOneAsset('assets/parentFolder/__3.0x_leaf_folder_/normalFile.png');
    });

    test('When asset path contains variant identifier as part of parent folder name scale is 1.0', () {
      _buildAndTestWithOneAsset('assets/parentFolder/__3.0x__/leafFolder/normalFile.png');
    });

    test('When asset path contains variant identifier in parent folder scale is 1.0', () {
      _buildAndTestWithOneAsset('assets/parentFolder/3.0x/leafFolder/normalFile.png');
    });
  });


  group('High-res device behavior tests', () {
    test('When asset is not main variant check scale is not 1.0', () {
      const String mainAssetPath = 'assets/normalFolder/normalFile.png';
      const String variantPath = 'assets/normalFolder/3.0x/normalFile.png';

      final Map<String, List<String>> assetBundleMap =
      <String, List<String>>{};

      assetBundleMap[mainAssetPath] = <String>[mainAssetPath, variantPath];

      final TestAssetBundle testAssetBundle = TestAssetBundle(
          assetBundleMap);

      final AssetImage assetImage = AssetImage(
          mainAssetPath,
          bundle: testAssetBundle);

      // we have the exact match for this scale, let's use it
      assetImage.obtainKey(const ImageConfiguration())
        .then(expectAsync1((AssetBundleImageKey bundleKey) {
          expect(bundleKey.name, mainAssetPath);
          expect(bundleKey.scale, 1.0);
        }));

      // we also have the exact match for this scale, let's use it
      assetImage.obtainKey(ImageConfiguration(
        bundle: testAssetBundle,
        devicePixelRatio: 3.0,
      )).then(expectAsync1((AssetBundleImageKey bundleKey) {
        expect(bundleKey.name, variantPath);
        expect(bundleKey.scale, 3.0);
      }));
    });

    test(
        'When high-res device and high-res asset not present in bundle then  return main variant', () {
      const String mainAssetPath = 'assets/normalFolder/normalFile.png';

      final Map<String, List<String>> assetBundleMap =
      <String, List<String>>{};

      assetBundleMap[mainAssetPath] = <String>[mainAssetPath];

      final TestAssetBundle testAssetBundle = TestAssetBundle(
          assetBundleMap);

      final AssetImage assetImage = AssetImage(
          mainAssetPath,
          bundle: TestAssetBundle(assetBundleMap));


      assetImage.obtainKey(const ImageConfiguration())
        .then(expectAsync1((AssetBundleImageKey bundleKey) {
          expect(bundleKey.name, mainAssetPath);
          expect(bundleKey.scale, 1.0);
        }));

      assetImage.obtainKey(ImageConfiguration(
        bundle: testAssetBundle,
        devicePixelRatio: 3.0)
      ).then(expectAsync1((AssetBundleImageKey bundleKey) {
        expect(bundleKey.name, mainAssetPath);
        expect(bundleKey.scale, 1.0);
      }));
    });
  });

  group('Regression - When assets available are 1.0 and 3.0 check devices with a range of scales', () {
    const String mainAssetPath = 'assets/normalFolder/normalFile.png';
    const String variantPath = 'assets/normalFolder/3.0x/normalFile.png';


    void _buildBundleAndTestVariantLogic(
      double deviceRatio,
      double chosenAssetRatio,
      String expectedAssetPath,
    ) {
      final Map<String, List<String>> assetBundleMap =
      <String, List<String>>{};

      assetBundleMap[mainAssetPath] = <String>[mainAssetPath, variantPath];

      final TestAssetBundle testAssetBundle = TestAssetBundle(
          assetBundleMap);

      final AssetImage assetImage = AssetImage(
          mainAssetPath,
          bundle: testAssetBundle);

      // we have 1.0 and 3.0, asking for 1.5 should give
      assetImage.obtainKey(ImageConfiguration(
        bundle: testAssetBundle,
        devicePixelRatio: deviceRatio)
      ).then(expectAsync1((AssetBundleImageKey bundleKey) {
        expect(bundleKey.name, expectedAssetPath);
        expect(bundleKey.scale, chosenAssetRatio);
      }));
    }

    test('Obvious case 1.0 - we have exact asset', () {
      _buildBundleAndTestVariantLogic(1.0, 1.0, mainAssetPath);
    });

    test('Obvious case 3.0 - we have exact asset', () {
      _buildBundleAndTestVariantLogic(3.0, 3.0, variantPath);
    });

    test('Typical case 2.0', () {
      _buildBundleAndTestVariantLogic(2.0, 1.0, mainAssetPath);
    });

    test('Borderline case 2.01', () {
      _buildBundleAndTestVariantLogic(2.01, 3.0, variantPath);
    });
    test('Borderline case 2.9', () {
      _buildBundleAndTestVariantLogic(2.9, 3.0, variantPath);
    });

    test('Typical case 4.0', () {
      _buildBundleAndTestVariantLogic(4.0, 3.0, variantPath);
    });
  });

}
