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

import 'package:ui/src/engine.dart';
import 'package:ui/ui_web/src/ui_web.dart' as ui_web;

class FakeAssetManager implements ui_web.AssetManager {
  FakeAssetManager();

  @override
  String get assetsDir => 'assets';

  @override
  String getAssetUrl(String asset) => asset;

  @override
  Future<ByteData> load(String assetKey) async {
    final ByteData? assetData = await _currentScope?.getAssetData(assetKey);
    if (assetData == null) {
      throw HttpFetchNoPayloadError(assetKey, status: 404);
    }
    return assetData;
  }

  @override
  Future<HttpFetchResponse> loadAsset(String asset) async {
    final ByteData? assetData = await _currentScope?.getAssetData(asset);
    if (assetData != null) {
      return MockHttpFetchResponse(
        url: asset,
        status: 200,
        payload: MockHttpFetchPayload(
          byteBuffer: assetData.buffer,
        ),
      );
    } else {
      return MockHttpFetchResponse(
        url: asset,
        status: 404,
      );
    }
  }

  FakeAssetScope pushAssetScope() {
    final FakeAssetScope scope = FakeAssetScope._(_currentScope);
    _currentScope = scope;
    return scope;
  }

  void popAssetScope(FakeAssetScope scope) {
    assert(_currentScope == scope);
    _currentScope = scope._parent;
  }

  FakeAssetScope? _currentScope;
}

class FakeAssetScope {
  FakeAssetScope._(this._parent);

  final FakeAssetScope? _parent;
  final Map<String, Future<ByteData> Function()> _assetFetcherMap = <String, Future<ByteData> Function()>{};

  void setAsset(String assetKey, ByteData assetData) {
    _assetFetcherMap[assetKey] = () async => assetData;
  }

  void setAssetPassthrough(String assetKey) {
    _assetFetcherMap[assetKey] = () async {
      return ByteData.view(await httpFetchByteBuffer(assetKey));
    };
  }

  Future<ByteData>? getAssetData(String assetKey) {
    final Future<ByteData> Function()? fetcher = _assetFetcherMap[assetKey];
    if (fetcher != null) {
      return fetcher();
    }
    if (_parent != null) {
      return _parent.getAssetData(assetKey);
    }
    return null;
  }
}

FakeAssetManager fakeAssetManager = FakeAssetManager();

ByteData stringAsUtf8Data(String string) {
  return ByteData.sublistView(utf8.encode(string));
}

const String ahemFontFamily = 'Ahem';
const String ahemFontUrl = '/assets/fonts/ahem.ttf';
const String robotoFontFamily = 'Roboto';
const String robotoTestFontUrl = '/assets/fonts/Roboto-Regular.ttf';
const String robotoVariableFontFamily = 'RobotoVariable';
const String robotoVariableFontUrl = '/assets/fonts/RobotoSlab-VariableFont_wght.ttf';

/// The list of test fonts, in the form of font family name - font file url pairs.
/// This list does not include embedded test fonts, which need to be loaded and
/// registered separately in [FontCollection.debugDownloadTestFonts].
const Map<String, String> testFontUrls = <String, String>{
  ahemFontFamily: ahemFontUrl,
  robotoFontFamily: robotoTestFontUrl,
  robotoVariableFontFamily: robotoVariableFontUrl,
};

FakeAssetScope configureDebugFontsAssetScope(FakeAssetManager manager) {
  final FakeAssetScope scope = manager.pushAssetScope();
  scope.setAsset('AssetManifest.json', stringAsUtf8Data('{}'));
  scope.setAsset('FontManifest.json', stringAsUtf8Data('''
  [
   {
      "family":"$robotoFontFamily",
      "fonts":[{"asset":"$robotoTestFontUrl"}]
   },
   {
      "family":"$ahemFontFamily",
      "fonts":[{"asset":"$ahemFontUrl"}]
   },
   {
      "family":"$robotoVariableFontFamily",
      "fonts":[{"asset":"$robotoVariableFontUrl"}]
    }
  ]'''));
  scope.setAssetPassthrough(robotoTestFontUrl);
  scope.setAssetPassthrough(ahemFontUrl);
  scope.setAssetPassthrough(robotoVariableFontUrl);
  return scope;
}
