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

// This file is hand-formatted.

import 'dart:async';
import 'dart:io';

import 'package:flutter/rendering.dart';
import 'package:flutter/widgets.dart';
import 'package:path/path.dart' as path;
import 'package:path_provider/path_provider.dart';
import 'package:rfw/rfw.dart';
import 'package:wasm/wasm.dart';

const String urlPrefix = 'https://raw.githubusercontent.com/flutter/packages/master/packages/rfw/example/wasm/logic';

const String interfaceUrl = '$urlPrefix/calculator.rfw';
const String logicUrl = '$urlPrefix/calculator.wasm';

void main() {
  runApp(WidgetsApp(color: const Color(0xFF000000), builder: (BuildContext context, Widget? navigator) => const Example()));
}

class Example extends StatefulWidget {
  const Example({Key? key}) : super(key: key);

  @override
  State<Example> createState() => _ExampleState();
}

class _ExampleState extends State<Example> {
  final Runtime _runtime = Runtime();
  final DynamicContent _data = DynamicContent();
  late final WasmInstance _logic;

  @override
  void initState() {
    super.initState();
    RendererBinding.instance.deferFirstFrame();
    _runtime.update(const LibraryName(<String>['core', 'widgets']), createCoreWidgets());
    _loadLogic();
  }

  late final WasmFunction _dataFetcher;

  Future<void> _loadLogic() async {
    final DateTime expiryDate = DateTime.now().subtract(const Duration(hours: 6));
    final Directory home = await getApplicationSupportDirectory();
    final File interfaceFile = File(path.join(home.path, 'cache.rfw'));
    if (!interfaceFile.existsSync() || interfaceFile.lastModifiedSync().isBefore(expiryDate)) {
      final HttpClientResponse client = await (await HttpClient().getUrl(Uri.parse(interfaceUrl))).close();
      await interfaceFile.writeAsBytes(await client.expand((List<int> chunk) => chunk).toList());
    }
    final File logicFile = File(path.join(home.path, 'cache.wasm'));
    if (!logicFile.existsSync() || logicFile.lastModifiedSync().isBefore(expiryDate)) {
      final HttpClientResponse client = await (await HttpClient().getUrl(Uri.parse(logicUrl))).close();
      await logicFile.writeAsBytes(await client.expand((List<int> chunk) => chunk).toList());
    }
    _runtime.update(const LibraryName(<String>['main']), decodeLibraryBlob(await interfaceFile.readAsBytes()));
    _logic = WasmModule(await logicFile.readAsBytes()).builder().build();
    _dataFetcher = _logic.lookupFunction('value');
    _updateData();
    setState(() { RendererBinding.instance.allowFirstFrame(); });
  }

  void _updateData() {
    final dynamic value = _dataFetcher.apply(const <Object?>[]);
    _data.update('value', <String, Object?>{ 'numeric': value, 'string': value.toString() });
  }

  List<Object?> _asList(Object? value) {
    if (value is List<Object?>)
      return value;
    return const <Object?>[];
  }

  @override
  Widget build(BuildContext context) {
    if (!RendererBinding.instance.sendFramesToEngine)
      return const SizedBox.shrink();
    return RemoteWidget(
      runtime: _runtime,
      data: _data,
      widget: const FullyQualifiedWidgetName(LibraryName(<String>['main']), 'root'),
      onEvent: (String name, DynamicMap arguments) {
        final WasmFunction function = _logic.lookupFunction(name);
        function.apply(_asList(arguments['arguments']));
        _updateData();
      },
    );
  }
}
