// Copyright 2016 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:collection';
import 'dart:ui' as ui;

import 'package:lib.app.dart/app_async.dart';
import 'package:fidl_fuchsia_sys/fidl_async.dart';
import 'package:fidl_fuchsia_math/fidl_async.dart' as fidl;
import 'package:fidl_fuchsia_ui_viewsv1/fidl_async.dart';
import 'package:fidl_fuchsia_ui_viewsv1token/fidl_async.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter/widgets.dart';
import 'package:fidl/fidl.dart';
import 'package:meta/meta.dart';
import 'package:zircon/zircon.dart';

import 'mozart.dart';

export 'package:fidl_fuchsia_ui_viewsv1token/fidl_async.dart' show ViewOwner;

ViewContainerProxy _initViewContainer() {
  // Analyzer doesn't know Handle must be dart:zircon's Handle
  final Handle handle = ScenicStartupInfo.takeViewContainer();
  if (handle == null) {
    return null;
  }
  final ViewContainerProxy proxy = new ViewContainerProxy()
    ..ctrl.bind(new InterfaceHandle<ViewContainer>(new Channel(handle)))
    ..setListener(_ViewContainerListenerImpl2.instance.createInterfaceHandle());

  assert(() {
    proxy.ctrl.whenClosed.then((_) async {
      print('ViewContainerProxy: closed');
    });
    return true;
  }());

  return proxy;
}

final ViewContainerProxy _viewContainer = _initViewContainer();

class _ViewContainerListenerImpl2 extends ViewContainerListener {
  final ViewContainerListenerBinding _binding =
      new ViewContainerListenerBinding();

  InterfaceHandle<ViewContainerListener> createInterfaceHandle() {
    return _binding.wrap(this);
  }

  static final _ViewContainerListenerImpl2 instance =
      new _ViewContainerListenerImpl2();

  @override
  Future<Null> onChildAttached(int childKey, ViewInfo childViewInfo) async {
    ChildViewConnection2 connection = _connections[childKey];
    connection?._onAttachedToContainer(childViewInfo);
  }

  @override
  Future<Null> onChildUnavailable(int childKey) async {
    ChildViewConnection2 connection = _connections[childKey];
    connection?._onUnavailable();
  }

  final Map<int, ChildViewConnection2> _connections =
      new HashMap<int, ChildViewConnection2>();
}

typedef ChildViewConnection2Callback = void Function(
    ChildViewConnection2 connection);
void _emptyConnectionCallback(ChildViewConnection2 c) {}

/// A connection with a child view.
///
/// Used with the [ChildView2] widget to display a child view.
class ChildViewConnection2 {
  ChildViewConnection2(this._viewOwner,
      {ChildViewConnection2Callback onAvailable,
      ChildViewConnection2Callback onUnavailable})
      : _onAvailableCallback = onAvailable ?? _emptyConnectionCallback,
        _onUnavailableCallback = onUnavailable ?? _emptyConnectionCallback,
        assert(_viewOwner != null);

  factory ChildViewConnection2.launch(String url, Launcher launcher,
      {InterfaceRequest<ComponentController> controller,
      InterfaceRequest<ServiceProvider> childServices,
      ChildViewConnection2Callback onAvailable,
      ChildViewConnection2Callback onUnavailable}) {
    final Services services = new Services();
    final LaunchInfo launchInfo =
        new LaunchInfo(url: url, directoryRequest: services.request());
    try {
      launcher.createComponent(launchInfo, controller);
      return new ChildViewConnection2.connect(services,
          childServices: childServices,
          onAvailable: onAvailable,
          onUnavailable: onUnavailable);
    } finally {
      services.close();
    }
  }

  factory ChildViewConnection2.connect(Services services,
      {InterfaceRequest<ServiceProvider> childServices,
      ChildViewConnection2Callback onAvailable,
      ChildViewConnection2Callback onUnavailable}) {
    final ViewProviderProxy viewProvider = new ViewProviderProxy();
    services.connectToService(viewProvider.ctrl);
    try {
      final InterfacePair<ViewOwner> viewOwner = new InterfacePair<ViewOwner>();
      viewProvider.createView(viewOwner.passRequest(), childServices);
      return new ChildViewConnection2(viewOwner.passHandle(),
          onAvailable: onAvailable, onUnavailable: onUnavailable);
    } finally {
      viewProvider.ctrl.close();
    }
  }

  final ChildViewConnection2Callback _onAvailableCallback;
  final ChildViewConnection2Callback _onUnavailableCallback;
  InterfaceHandle<ViewOwner> _viewOwner;

  static int _nextViewKey = 1;
  int _viewKey;

  ViewProperties _currentViewProperties;

  VoidCallback _onViewInfoAvailable;
  ViewInfo _viewInfo;
  ui.SceneHost _sceneHost;

  void _onAttachedToContainer(ViewInfo viewInfo) {
    assert(_viewInfo == null);
    _viewInfo = viewInfo;
    if (_onViewInfoAvailable != null) {
      _onViewInfoAvailable();
    }
    _onAvailableCallback(this);
  }

  void _onUnavailable() {
    _viewInfo = null;
    _onUnavailableCallback(this);
  }

  void _addChildToViewHost() {
    if (_viewContainer == null) {
      return;
    }
    assert(_attached);
    assert(_viewOwner != null);
    assert(_viewKey == null);
    assert(_viewInfo == null);
    assert(_sceneHost == null);

    final EventPairPair pair = new EventPairPair();
    assert(pair.status == ZX.OK);

    // Analyzer doesn't know Handle must be dart:zircon's Handle
    _sceneHost = new ui.SceneHost(pair.first.passHandle());
    _viewKey = _nextViewKey++;
    _viewContainer.addChild(_viewKey, _viewOwner, pair.second);
    _viewOwner = null;
    assert(!_ViewContainerListenerImpl2.instance._connections
        .containsKey(_viewKey));
    _ViewContainerListenerImpl2.instance._connections[_viewKey] = this;
  }

  void _removeChildFromViewHost() {
    if (_viewContainer == null) {
      return;
    }
    assert(!_attached);
    assert(_viewOwner == null);
    assert(_viewKey != null);
    assert(_sceneHost != null);
    assert(_ViewContainerListenerImpl2.instance._connections[_viewKey] == this);
    final ChannelPair pair = new ChannelPair();
    assert(pair.status == ZX.OK);
    _ViewContainerListenerImpl2.instance._connections.remove(_viewKey);
    _viewOwner = new InterfaceHandle<ViewOwner>(pair.first);
    _viewContainer.removeChild(
        _viewKey, new InterfaceRequest<ViewOwner>(pair.second));
    _viewKey = null;
    _viewInfo = null;
    _currentViewProperties = null;
    _sceneHost.dispose();
    _sceneHost = null;
  }

  /// Only call when the connection is available.
  void requestFocus() {
    if (_viewKey != null) {
      _viewContainer.requestFocus(_viewKey);
    }
  }

  // The number of render objects attached to this view. In between frames, we
  // might have more than one connected if we get added to a new render object
  // before we get removed from the old render object. By the time we get around
  // to computing our layout, we must be back to just having one render object.
  int _attachments = 0;
  bool get _attached => _attachments > 0;

  void _attach() {
    assert(_attachments >= 0);
    ++_attachments;
    if (_viewKey == null) {
      _addChildToViewHost();
    }
  }

  void _detach() {
    assert(_attached);
    --_attachments;
    scheduleMicrotask(_removeChildFromViewHostIfNeeded);
  }

  void _removeChildFromViewHostIfNeeded() {
    assert(_attachments >= 0);
    if (_attachments == 0 && _viewKey != null) {
      _removeChildFromViewHost();
    }
  }

  ViewProperties _createViewProperties(
      double width,
      double height,
      double insetTop,
      double insetRight,
      double insetBottom,
      double insetLeft,
      bool focusable) {
    if (_currentViewProperties != null &&
        _currentViewProperties.viewLayout.size.width == width &&
        _currentViewProperties.viewLayout.size.height == height &&
        _currentViewProperties.viewLayout.inset.top == insetTop &&
        _currentViewProperties.viewLayout.inset.right == insetRight &&
        _currentViewProperties.viewLayout.inset.bottom == insetBottom &&
        _currentViewProperties.viewLayout.inset.left == insetLeft &&
        (_currentViewProperties.customFocusBehavior == null ||
                _currentViewProperties.customFocusBehavior.allowFocus) ==
            focusable) {
      return null;
    }

    fidl.SizeF size = new fidl.SizeF(width: width, height: height);
    fidl.InsetF inset = new fidl.InsetF(
        top: insetTop, right: insetRight, bottom: insetBottom, left: insetLeft);
    ViewLayout viewLayout = new ViewLayout(size: size, inset: inset);
    final customFocusBehavior = new CustomFocusBehavior(allowFocus: focusable);
    return _currentViewProperties = new ViewProperties(
      viewLayout: viewLayout,
      customFocusBehavior: customFocusBehavior,
    );
  }

  void _setChildProperties(
    double width,
    double height,
    double insetTop,
    double insetRight,
    double insetBottom,
    double insetLeft,
    bool focusable,
  ) {
    assert(_attached);
    assert(_attachments == 1);
    assert(_viewKey != null);
    if (_viewContainer == null) {
      return;
    }
    ViewProperties viewProperties = _createViewProperties(
        width, height, insetTop, insetRight, insetBottom, insetLeft, focusable);
    if (viewProperties == null) {
      return;
    }
    _viewContainer.setChildProperties(_viewKey, viewProperties);
  }
}

class _RenderChildView2 extends RenderBox {
  /// Creates a child view render object.
  _RenderChildView2({
    ChildViewConnection2 connection,
    bool hitTestable = true,
    bool focusable = true,
  })  : _connection = connection,
        _hitTestable = hitTestable,
        _focusable = focusable,
        assert(hitTestable != null);

  /// The child to display.
  ChildViewConnection2 get connection => _connection;
  ChildViewConnection2 _connection;
  set connection(ChildViewConnection2 value) {
    if (value == _connection) {
      return;
    }
    if (attached && _connection != null) {
      _connection._detach();
      assert(_connection._onViewInfoAvailable != null);
      _connection._onViewInfoAvailable = null;
    }
    _connection = value;
    if (attached && _connection != null) {
      _connection._attach();
      assert(_connection._onViewInfoAvailable == null);
      _connection._onViewInfoAvailable = markNeedsPaint;
    }
    if (_connection == null) {
      markNeedsPaint();
    } else {
      markNeedsLayout();
    }
  }

  /// Whether this child should be included during hit testing.
  bool get hitTestable => _hitTestable;
  bool _hitTestable;
  set hitTestable(bool value) {
    assert(value != null);
    if (value == _hitTestable) {
      return;
    }
    _hitTestable = value;
    if (_connection != null) {
      markNeedsPaint();
    }
  }

  /// Whether this child should be able to recieve focus events
  bool get focusable => _focusable;
  bool _focusable;
  set focusable(bool value) {
    assert(value != null);
    if (value == _focusable) {
      return;
    }
    _focusable = value;
    if (_connection != null) {
      markNeedsPaint();
    }
  }

  @override
  void attach(PipelineOwner owner) {
    super.attach(owner);
    if (_connection != null) {
      _connection._attach();
      assert(_connection._onViewInfoAvailable == null);
      _connection._onViewInfoAvailable = markNeedsPaint;
    }
  }

  @override
  void detach() {
    if (_connection != null) {
      _connection._detach();
      assert(_connection._onViewInfoAvailable != null);
      _connection._onViewInfoAvailable = null;
    }
    super.detach();
  }

  @override
  bool get alwaysNeedsCompositing => true;

  TextPainter _debugErrorMessage;

  double _width;
  double _height;

  @override
  void performLayout() {
    size = constraints.biggest;

    // Ignore if we have no child view connection.
    if (_connection == null) {
      return;
    }

    if (_width != null && _height != null) {
      double deltaWidth = (_width - size.width).abs();
      double deltaHeight = (_height - size.height).abs();

      // Ignore insignificant changes in size that are likely rounding errors.
      if (deltaWidth < 0.0001 && deltaHeight < 0.0001) {
        return;
      }
    }

    _width = size.width;
    _height = size.height;
    _connection._setChildProperties(
        _width, _height, 0.0, 0.0, 0.0, 0.0, _focusable);
    assert(() {
      if (_viewContainer == null) {
        _debugErrorMessage ??= new TextPainter(
            text: const TextSpan(
                text:
                    'Child views are supported only when running in Scenic.'));
        _debugErrorMessage.layout(minWidth: size.width, maxWidth: size.width);
      }
      return true;
    }());
  }

  @override
  bool hitTestSelf(Offset position) => true;

  @override
  void paint(PaintingContext context, Offset offset) {
    assert(needsCompositing);
    if (_connection?._viewInfo != null) {
      context.addLayer(new ChildSceneLayer(
        offset: offset,
        width: _width,
        height: _height,
        sceneHost: _connection._sceneHost,
        hitTestable: hitTestable,
      ));
    }
    assert(() {
      if (_viewContainer == null) {
        context.canvas.drawRect(
            offset & size, new Paint()..color = const Color(0xFF0000FF));
        _debugErrorMessage.paint(context.canvas, offset);
      }
      return true;
    }());
  }

  @override
  void debugFillProperties(DiagnosticPropertiesBuilder description) {
    super.debugFillProperties(description);
    description.add(
      new DiagnosticsProperty<ChildViewConnection2>(
        'connection',
        connection,
      ),
    );
  }
}

/// A layer that represents content from another process.
class ChildSceneLayer extends Layer {
  /// Creates a layer that displays content rendered by another process.
  ///
  /// All of the arguments must not be null.
  ChildSceneLayer({
    this.offset = Offset.zero,
    this.width = 0.0,
    this.height = 0.0,
    this.sceneHost,
    this.hitTestable = true,
  });

  /// Offset from parent in the parent's coordinate system.
  Offset offset;

  /// The horizontal extent of the child, in logical pixels.
  double width;

  /// The vertical extent of the child, in logical pixels.
  double height;

  /// The host site for content rendered by the child.
  ui.SceneHost sceneHost;

  /// Whether this child should be included during hit testing.
  ///
  /// Defaults to true.
  bool hitTestable;

  @override
  ui.EngineLayer addToScene(ui.SceneBuilder builder,
      [Offset layerOffset = Offset.zero]) {
    builder.addChildScene(
      offset: offset + layerOffset,
      width: width,
      height: height,
      sceneHost: sceneHost,
      hitTestable: hitTestable,
    );
    return null;
  }

  @override
  void debugFillProperties(DiagnosticPropertiesBuilder description) {
    super.debugFillProperties(description);
    description
      ..add(new DiagnosticsProperty<Offset>('offset', offset))
      ..add(new DoubleProperty('width', width))
      ..add(new DoubleProperty('height', height))
      ..add(new DiagnosticsProperty<ui.SceneHost>('sceneHost', sceneHost))
      ..add(new DiagnosticsProperty<bool>('hitTestable', hitTestable));
  }

  @override
  S find<S>(Offset regionOffset) => null;
}

/// A widget that is replaced by content from another process.
///
/// Requires a [MediaQuery] ancestor to provide appropriate media information to
/// the child.
@immutable
class ChildView2 extends LeafRenderObjectWidget {
  /// Creates a widget that is replaced by content from another process.
  ChildView2({this.connection, this.hitTestable = true, this.focusable = true})
      : super(key: new GlobalObjectKey(connection));

  /// A connection to the child whose content will replace this widget.
  final ChildViewConnection2 connection;

  /// Whether this child should be included during hit testing.
  ///
  /// Defaults to true.
  final bool hitTestable;

  /// Whether this child and its children should be allowed to receive focus.
  ///
  /// Defaults to true.
  final bool focusable;

  @override
  _RenderChildView2 createRenderObject(BuildContext context) {
    return new _RenderChildView2(
      connection: connection,
      hitTestable: hitTestable,
      focusable: focusable,
    );
  }

  @override
  void updateRenderObject(
      BuildContext context, _RenderChildView2 renderObject) {
    renderObject
      ..connection = connection
      ..hitTestable = hitTestable
      ..focusable = focusable;
  }
}

class View2 {
  /// Provide services to Scenic throught |provider|.
  ///
  /// |services| should contain the list of service names offered by the
  /// |provider|.
  static void offerServiceProvider(
      InterfaceHandle<ServiceProvider> provider, List<String> services) {
    // Analyzer doesn't know Handle must be dart:zircon's Handle
    Scenic.offerServiceProvider(provider.passChannel().handle, services);
  }
}
