// Copyright 2017 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:convert';
import 'dart:developer' show Timeline;
import 'dart:typed_data';

import 'package:fidl/fidl.dart';
import 'package:fidl_fuchsia_mem/fidl_async.dart' as fuchsia_mem;
import 'package:fidl_fuchsia_modular/fidl_async.dart';
import 'package:fidl_fuchsia_ui_views/fidl_async.dart' show ViewHolderToken;
import 'package:fuchsia_logger/logger.dart';
import 'package:fuchsia_modular/lifecycle.dart' as lifecycle;
import 'package:fuchsia_services/services.dart';
import 'package:lib.story_shell/common.dart';
import 'package:zircon/zircon.dart';

import 'models/surface/surface_graph.dart';
import 'models/surface/surface_properties.dart';
import 'visual_state_watcher.dart';

/// An implementation of the [StoryShell] interface.
class StoryShellImpl extends StoryShell {
  final StoryShellBinding _storyShellBinding = StoryShellBinding();
  final StoryShellContextProxy _storyShellContext = StoryShellContextProxy();
  final LinkProxy _linkProxy = LinkProxy();
  final KeyListener keyListener;
  final StoryVisualStateWatcherBinding _visualStateWatcherBinding =
      StoryVisualStateWatcherBinding();
  final SurfaceGraph surfaceGraph;
  final String _storyShellLinkName = 'story_shell_state';
  final StreamController<String> _focusEventStreamController =
      StreamController.broadcast();
  String _lastFocusedSurfaceId;
  lifecycle.Lifecycle _lifecycle;
  VisualStateWatcher _storyVisualStateWatcher;

  StoryShellImpl({this.surfaceGraph, this.keyListener});

  /// StoryShell
  @override
  Future<void> initialize(
      InterfaceHandle<StoryShellContext> contextHandle) async {
    _storyVisualStateWatcher = VisualStateWatcher(
        keyListener: keyListener, storyShellContext: _storyShellContext);
    _storyShellContext.ctrl.bind(contextHandle);
    await _storyShellContext.watchVisualState(
        _visualStateWatcherBinding.wrap(_storyVisualStateWatcher));
    await _storyShellContext
        .getLink(_linkProxy.ctrl.request())
        .then((v) => reloadStoryState())
        .then((onLinkContentsFetched));
    surfaceGraph.addListener(() {
      String surfaceId = surfaceGraph.focused?.node?.value;
      if (surfaceId != null && surfaceId != _lastFocusedSurfaceId) {
        _focusEventStreamController.add(surfaceId);
        _lastFocusedSurfaceId = surfaceId;
      }
    });
  }

  /// Bind an [InterfaceRequest] for a [StoryShell] interface to this object.
  void bindStoryShell(InterfaceRequest<StoryShell> request) {
    _storyShellBinding.bind(this, request);
  }

  /// Introduce a new Surface and corresponding [ViewHolderToken] to the current
  /// Story.
  ///
  /// The Surface may have a relationship with its parent surface.
  @override
  Future<void> addSurface(
    ViewConnection viewConnection,
    SurfaceInfo surfaceInfo,
  ) async {
    Timeline.instantSync(
        'connecting surface ${viewConnection.surfaceId} with parent ${surfaceInfo.parentId}');
    log.fine(
        'Connecting surface ${viewConnection.surfaceId} with parent ${surfaceInfo.parentId}');

    /// ignore: cascade_invocations
    log.fine('Were passed manifest: $surfaceInfo.moduleManifest');
    surfaceGraph
      ..addSurface(
        viewConnection.surfaceId,
        SurfaceProperties(source: surfaceInfo.moduleSource),
        surfaceInfo.parentId,
        surfaceInfo.surfaceRelation ?? const SurfaceRelation(),
        surfaceInfo.moduleManifest != null
            ? surfaceInfo.moduleManifest.compositionPattern
            : '',
        surfaceInfo.moduleManifest != null
            ? surfaceInfo.moduleManifest.placeholderColor
            : '',
      )
      ..connectViewFromViewHolderToken(
          viewConnection.surfaceId,
          ViewHolderToken(
              value:
                  EventPair(viewConnection.owner.passChannel().passHandle())));
  }

  /// Focus the surface with this id
  @override
  Future<void> focusSurface(String surfaceId) async {
    Timeline.instantSync('focusing view',
        arguments: {'surfaceId': '$surfaceId'});
    surfaceGraph.focusSurface(surfaceId);
    return persistStoryState();
  }

  /// Defocus the surface with this id
  @override
  Future<void> defocusSurface(String surfaceId) async {
    Timeline.instantSync('defocusing view',
        arguments: {'surfaceId': '$surfaceId'});
    surfaceGraph.dismissSurface(surfaceId);
    return persistStoryState();
  }

  @Deprecated('Deprecated')
  @override
  Future<void> addContainer(
    String containerName,
    String parentId,
    SurfaceRelation relation,
    List<ContainerLayout> layouts,
    List<ContainerRelationEntry> relationships,
    List<ContainerView> views,
  ) async {
    // Add a root node for the container
    Timeline.instantSync('adding container', arguments: {
      'containerName': '$containerName',
      'parentId': '$parentId'
    });
    surfaceGraph.addContainer(
      containerName,
      SurfaceProperties(),
      parentId,
      relation,
      layouts,
    );
    Map<String, ContainerRelationEntry> nodeMap =
        <String, ContainerRelationEntry>{};
    Map<String, List<String>> parentChildrenMap = <String, List<String>>{};
    Map<String, ViewHolderToken> viewMap = <String, ViewHolderToken>{};
    for (ContainerView view in views) {
      viewMap[view.nodeName] = ViewHolderToken(
          value: EventPair(view.owner.passChannel().passHandle()));
    }
    for (ContainerRelationEntry relatedNode in relationships) {
      nodeMap[relatedNode.nodeName] = relatedNode;
      parentChildrenMap
          .putIfAbsent(relatedNode.parentNodeName, () => <String>[])
          .add(relatedNode.nodeName);
    }
    List<String> nodeQueue =
        views.map((ContainerView v) => v.nodeName).toList();
    List<String> addedParents = <String>[containerName];
    int i = 0;
    while (nodeQueue.isNotEmpty) {
      String nodeId = nodeQueue.elementAt(i);
      String parentId = nodeMap[nodeId].parentNodeName;
      if (addedParents.contains(parentId)) {
        for (nodeId in parentChildrenMap[parentId]) {
          SurfaceProperties prop = SurfaceProperties()
            ..containerMembership = <String>[containerName]
            ..containerLabel = nodeId;
          surfaceGraph.addSurface(
              nodeId, prop, parentId, nodeMap[nodeId].relationship, null, '');
          addedParents.add(nodeId);
          surfaceGraph.connectViewFromViewHolderToken(nodeId, viewMap[nodeId]);
          nodeQueue.remove(nodeId);
          surfaceGraph.focusSurface(nodeId);
        }
        i = 0;
      } else {
        i++;
        if (i > nodeQueue.length) {
          log.warning('''Error iterating through container children.
          All nodes iterated without finding all parents specified in
          Container Relations''');
          return;
        }
      }
    }
  }

  @override
  Future<void> removeSurface(String surfaceId) async {
    return surfaceGraph.removeSurface(surfaceId);
  }

  @override
  Future<void> reconnectView(ViewConnection viewConnection) async {
    // TODO (jphsiao): implement
  }

  @override
  Future<void> updateSurface(
    ViewConnection viewConnection,
    SurfaceInfo surfaceInfo,
  ) async {
    // TODO (jphsiao): implement
  }

  Future<fuchsia_mem.Buffer> reloadStoryState() async {
    return _linkProxy.get([_storyShellLinkName]);
  }

  void onLinkContentsFetched(fuchsia_mem.Buffer buffer) {
    var dataVmo = SizedVmo(buffer.vmo.handle, buffer.size);
    var data = dataVmo.read(buffer.size);
    dataVmo.close();
    dynamic decoded = jsonDecode(utf8.decode(data.bytesAsUint8List()));
    if (decoded is Map<String, dynamic>) {
      surfaceGraph.reload(decoded.cast<String, dynamic>());
    }
  }

  Future<void> persistStoryState() async {
    String encoded = json.encode(surfaceGraph);
    var jsonList = Uint8List.fromList(utf8.encode(encoded));
    var data = fuchsia_mem.Buffer(
      vmo: SizedVmo.fromUint8List(jsonList),
      size: jsonList.length,
    );
    await _linkProxy.set([_storyShellLinkName], data);
  }

  @override
  Stream<String> get onSurfaceFocused => _focusEventStreamController.stream;

  /// Start advertising the StoryShell service, and bind lifecycle to
  /// termination
  void advertise() {
    StartupContext.fromStartupInfo().outgoing.addPublicService(
      (InterfaceRequest<StoryShell> request) {
        Timeline.instantSync('story shell request');
        log.fine('Received binding request for StoryShell');
        bindStoryShell(request);
      },
      StoryShell.$serviceName,
    );
    _lifecycle ??= lifecycle.Lifecycle();
  }
}
