// Copyright 2018 The Fuchsia 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:typed_data';

import 'package:async/async.dart';
import 'package:fidl/fidl.dart';
import 'package:fidl_fuchsia_mem/fidl_async.dart' as fuchsia_mem;
import 'package:fidl_fuchsia_modular/fidl_async.dart' as fidl_modular;
import 'package:meta/meta.dart';
import 'package:zircon/zircon.dart';

import '../entity.dart';
import '../entity_exceptions.dart';

typedef EntityProxyFactory = FutureOr<fidl_modular.Entity> Function();

/// A concrete implementation of the [Entity] class.
class EntityImpl implements Entity {
  final _proxyMemo = AsyncMemoizer<fidl_modular.Entity>();

  @override
  final String type;

  final _entityReferenceMemo = AsyncMemoizer<String>();

  /// A function which returns a bound proxy on demand. This method will only be
  /// called once.
  final EntityProxyFactory proxyFactory;

  /// Constructs an instance of [EntityImpl].
  EntityImpl({
    @required this.proxyFactory,
    @required this.type,
  })  : assert(proxyFactory != null),
        assert(type != null && type.isNotEmpty);

  @override
  Future<Uint8List> getData() =>
      _getProxy().then((p) => p.getData(type)).then(_unwrapBuffer);

  @override
  Future<String> getEntityReference() => _entityReferenceMemo
      .runOnce(() => _getProxy().then((p) => p.getReference()));

  @override
  Stream<Uint8List> watch() {
    final controller = StreamController<fuchsia_mem.Buffer>();
    final watcher = _EntityWatcher(controller.add);

    // if the user closed the stream we close the binding to the watcher
    controller.onCancel = watcher.binding.close;

    // if the connection closes then we close the stream
    watcher.binding.whenClosed.then((_) {
      if (!controller.isClosed) {
        controller.close();
      }
    });

    _getProxy().then((proxy) {
      proxy.watch(type, watcher.getInterfaceHandle());
    });

    return controller.stream.asyncMap(_unwrapBuffer);
  }

  @override
  Future<void> write(Uint8List value) async {
    ArgumentError.checkNotNull(value, 'value');

    final vmo = SizedVmo.fromUint8List(value);
    final buffer = fuchsia_mem.Buffer(vmo: vmo, size: value.length);

    final proxy = await _getProxy();
    final result = await proxy.writeData(type, buffer);
    if (result != fidl_modular.EntityWriteStatus.ok) {
      throw EntityWriteException(result);
    }
  }

  Future<fidl_modular.Entity> _getProxy() => _proxyMemo.runOnce(proxyFactory);

  Uint8List _unwrapBuffer(fuchsia_mem.Buffer buffer) {
    final dataVmo = SizedVmo(buffer.vmo.handle, buffer.size);
    final result = dataVmo.read(buffer.size);

    if (result.status != 0) {
      throw Exception(
          'VMO read faile with status [${result.status}] when trying to read entity data with type [$type]');
    }

    dataVmo.close();
    return result.bytesAsUint8List();
  }
}

class _EntityWatcher implements fidl_modular.EntityWatcher {
  final fidl_modular.EntityWatcherBinding binding =
      fidl_modular.EntityWatcherBinding();
  final void Function(fuchsia_mem.Buffer) onUpdatedFunc;

  _EntityWatcher(this.onUpdatedFunc) : assert(onUpdatedFunc != null);

  InterfaceHandle<fidl_modular.EntityWatcher> getInterfaceHandle() {
    return binding.wrap(this);
  }

  @override
  Future<void> onUpdated(fuchsia_mem.Buffer data) async => onUpdatedFunc(data);
}
