// 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:ui';

import 'package:fidl/fidl.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:zircon/zircon.dart';

import 'internal/_child_scene_layer.dart';
import 'internal/_mozart.dart';
import 'internal/_view_container_listener_impl.dart';

typedef ChildViewConnectionCallback = void Function(
    ChildViewConnection connection);

final ViewContainerProxy _viewContainer = _initViewContainer();

void _emptyConnectionCallback(ChildViewConnection c) {}

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 = ViewContainerProxy()
    ..ctrl.bind(InterfaceHandle<ViewContainer>(Channel(handle)))
    ..setListener(ViewContainerListenerImpl().createInterfaceHandle());

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

  return proxy;
}

/// A connection with a child view.
///
/// Used with the [ChildView] widget to display a child view.
class ChildViewConnection {
  static int _nextViewKey = 1;

  // TODO consider providing this API after MS-2293 is fixed
  // factory ChildViewConnection.launch(String url, Launcher launcher,
  //     {InterfaceRequest<ComponentController> controller,
  //     InterfaceRequest<ServiceProvider> childServices,
  //     ChildViewConnectionCallback onAvailable,
  //     ChildViewConnectionCallback onUnavailable}) {
  //   final Services services = Services();
  //   final LaunchInfo launchInfo =
  //       LaunchInfo(url: url, directoryRequest: services.request());
  //   try {
  //     launcher.createComponent(launchInfo, controller);
  //     return ChildViewConnection.connect(services,
  //         childServices: childServices,
  //         onAvailable: onAvailable,
  //         onUnavailable: onUnavailable);
  //   } finally {
  //     services.close();
  //   }
  // }

  // TODO consider providing this API after MS-2293 is fixed
  // factory ChildViewConnection.connect(Services services,
  //     {InterfaceRequest<ServiceProvider> childServices,
  //     ChildViewConnectionCallback onAvailable,
  //     ChildViewConnectionCallback onUnavailable}) {
  // final app.ViewProviderProxy viewProvider = new app.ViewProviderProxy();
  // services.connectToService(viewProvider.ctrl);
  // try {
  //   EventPairPair viewTokens = new EventPairPair();
  //   assert(viewTokens.status == ZX.OK);

  //   viewProvider.createView(viewTokens.second, childServices, null);
  //   return new ChildViewConnection.fromViewHolderToken(viewTokens.first,
  //       onAvailable: onAvailable, onUnavailable: onUnavailable);
  //   } finally {
  //     viewProvider.ctrl.close();
  //   }
  // }

  final ChildViewConnectionCallback _onAvailableCallback;
  final ChildViewConnectionCallback _onUnavailableCallback;
  EventPair _viewHolderToken;

  int _viewKey;
  ViewProperties _currentViewProperties;

  VoidCallback _onViewInfoAvailable;

  ViewInfo _viewInfo;
  SceneHost _sceneHost;
  int _attachments = 0;

  /// Deprecated.
  ChildViewConnection(InterfaceHandle<ViewOwner> viewOwner,
      {ChildViewConnectionCallback onAvailable,
      ChildViewConnectionCallback onUnavailable})
      : this.fromViewHolderToken(
            new EventPair(viewOwner?.passChannel()?.passHandle()),
            onAvailable: onAvailable,
            onUnavailable: onUnavailable);

  /// Constructs |ChildViewConnection| from a token.
  ChildViewConnection.fromViewHolderToken(EventPair viewHolderToken,
      {ChildViewConnectionCallback onAvailable,
      ChildViewConnectionCallback onUnavailable})
      : _onAvailableCallback = onAvailable ?? _emptyConnectionCallback,
        _onUnavailableCallback = onUnavailable ?? _emptyConnectionCallback,
        _viewHolderToken = viewHolderToken {
    assert(_viewHolderToken != null);
  }

  bool get _attached => _attachments > 0;

  /// TODO add documnetation
  void onAttachedToContainer(ViewInfo viewInfo) {
    assert(_viewInfo == null);
    _viewInfo = viewInfo;
    if (_onViewInfoAvailable != null) {
      _onViewInfoAvailable();
    }
    _onAvailableCallback(this);
  }

  /// TODO add documentation
  void onUnavailable() {
    _viewInfo = null;
    _onUnavailableCallback(this);
  }

  /// 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 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.
  /// TODO add documentation
  void sendSizeChangeHintHack(
      double widthChangeFactor, double heightChangeFactor) {
    assert(_attached);
    assert(_attachments == 1);
    if (_viewKey == null) {
      return;
    }

    if (_viewContainer == null) {
      return;
    }

    _viewContainer.sendSizeChangeHintHack(
        _viewKey, widthChangeFactor, heightChangeFactor);
  }

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

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

    // Analyzer doesn't know Handle must be dart:zircon's Handle
    _sceneHost = new SceneHost(sceneTokens.first.passHandle());
    _viewKey = _nextViewKey++;
    _viewContainer.addChild2(_viewKey, _viewHolderToken, sceneTokens.second);
    _viewHolderToken = null;
    assert(!ViewContainerListenerImpl().containsConnectionForKey(_viewKey));
    ViewContainerListenerImpl().addConnectionForKey(_viewKey, this);
  }

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

  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 = fidl.SizeF(width: width, height: height);
    fidl.InsetF inset = fidl.InsetF(
        top: insetTop, right: insetRight, bottom: insetBottom, left: insetLeft);
    ViewLayout viewLayout = ViewLayout(size: size, inset: inset);
    final customFocusBehavior = CustomFocusBehavior(allowFocus: focusable);
    return _currentViewProperties = ViewProperties(
      viewLayout: viewLayout,
      customFocusBehavior: customFocusBehavior,
    );
  }

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

  void _removeChildFromViewHost() {
    if (_viewContainer == null) {
      return;
    }
    assert(!_attached);
    assert(_viewHolderToken == null);
    assert(_viewKey != null);
    assert(_sceneHost != null);
    assert(ViewContainerListenerImpl().getConnectionForKey(_viewKey) == this);
    final EventPairPair viewTokens = new EventPairPair();
    assert(viewTokens.status == ZX.OK);
    ViewContainerListenerImpl().removeConnectionForKey(_viewKey);
    _viewHolderToken = viewTokens.first;
    _viewContainer.removeChild2(_viewKey, viewTokens.second);
    _viewKey = null;
    _viewInfo = null;
    _currentViewProperties = null;
    _sceneHost.dispose();
    _sceneHost = null;
  }

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

  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);
  }
}

/// TODO add documentation
class RenderChildView extends RenderBox {
  ChildViewConnection _connection;

  bool _hitTestable;
  bool _focusable;
  TextPainter _debugErrorMessage;

  double _width;
  double _height;

  /// Creates a child view render object.
  RenderChildView({
    ChildViewConnection connection,
    bool hitTestable = true,
    bool focusable = true,
  })  : _connection = connection,
        _hitTestable = hitTestable,
        _focusable = focusable,
        assert(hitTestable != null);

  @override
  bool get alwaysNeedsCompositing => true;

  /// The child to display.
  ChildViewConnection get connection => _connection;
  set connection(ChildViewConnection 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 able to recieve focus events
  bool get focusable => _focusable;

  set focusable(bool value) {
    assert(value != null);
    if (value == _focusable) {
      return;
    }
    _focusable = value;
    if (_connection != null) {
      markNeedsPaint();
    }
  }

  /// Whether this child should be included during hit testing.
  bool get hitTestable => _hitTestable;

  set hitTestable(bool value) {
    assert(value != null);
    if (value == _hitTestable) {
      return;
    }
    _hitTestable = 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 debugFillProperties(DiagnosticPropertiesBuilder description) {
    super.debugFillProperties(description);
    description.add(
      DiagnosticsProperty<ChildViewConnection>(
        'connection',
        connection,
      ),
    );
  }

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

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

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

  @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 ??= TextPainter(
            text: const TextSpan(
                text:
                    'Child views are supported only when running in Scenic.'));
        _debugErrorMessage.layout(minWidth: size.width, maxWidth: size.width);
      }
      return true;
    }());
  }
}
