// 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:math';
import 'dart:typed_data' show Uint8List;

import 'package:fidl/fidl.dart';
import 'package:fidl_fuchsia_ledger/fidl_async.dart' as ledger;
import 'package:fidl_fuchsia_modular/fidl_async.dart' as modular;
import 'package:fuchsia_logger/logger.dart';
import 'package:lib.widgets.dart/model.dart';

import '../ledger_helpers.dart';

/// The model for the todo list module.
class TodoListModel extends Model {
  final Random _random = Random(DateTime.now().millisecondsSinceEpoch);

  final ledger.PageWatcherBinding _pageWatcherBinding =
      ledger.PageWatcherBinding();

  final ledger.LedgerProxy _ledger = ledger.LedgerProxy();

  final ledger.PageProxy _page = ledger.PageProxy();

  /// The todo items. The source of truth is Ledger, so [_items] should never be
  /// modified directly.
  Map<List<int>, String> _items = <List<int>, String>{};

  /// Retrieves the todo items.
  Map<List<int>, String> get items => _items;

  /// Call this method to connect the model
  void connect(modular.ComponentContext componentContext) {
    _ledger.ctrl.whenClosed.then((_) => log.warning('Ledger disconnected'));
    componentContext.getLedger(_ledger.ctrl.request());

    _readInitialData();
  }

  Future<void> _readInitialData() async {
    await _ledger.getRootPage(_page.ctrl.request());

    final snapshot = ledger.PageSnapshotProxy();
    await _page.getSnapshotNew(
      snapshot.ctrl.request(),
      new Uint8List(0),
      _pageWatcherBinding.wrap(_PageWatcher(this)),
    );
    _readItems(snapshot);
  }

  /// Call when the module should be terminated.
  Future<void> onTerminate() async {
    _pageWatcherBinding.close();
    _ledger.ctrl.close();
    _page.ctrl.close();
  }

  /// Marks the item of the given [id] as done.
  void markItemDone(List<int> id) {
    _page.deleteNew(id);
  }

  /// Adds a new todo item with the given [content].
  void addItem(String content) {
    _page.putNew(_makeKey(), utf8.encode(content));
  }

  void _readItems(ledger.PageSnapshotProxy snapshot) {
    getEntriesFromSnapshot(snapshot,
        (ledger.Status status, Map<List<int>, String> items) {
      if (validateLedgerResponse(status, 'getEntries')) {
        _items = items;
        notifyListeners();
        snapshot.ctrl.close();
      }
    });
  }

  Uint8List _makeKey() {
    Uint8List key = new Uint8List(16);
    for (int i = 0; i < 16; i++) {
      key[i] = _random.nextInt(256);
    }
    return key;
  }
}

class _PageWatcher extends ledger.PageWatcher {
  final TodoListModel _model;

  _PageWatcher(this._model);

  /// Implementation of PageWatcher.onChange().
  @override
  Future<InterfaceRequest<ledger.PageSnapshot>> onChange(
    ledger.PageChange pageChange,
    ledger.ResultState resultState,
  ) async {
    if (resultState != ledger.ResultState.completed &&
        resultState != ledger.ResultState.partialStarted) {
      log.info('Unexpected result state in Ledger watcher: $resultState');
      return null;
    }
    final snapshot = ledger.PageSnapshotProxy();

    // need to call request() before _readItems so that the object
    // is bound and the subsequent reads do not fail
    final request = snapshot.ctrl.request();

    _model._readItems(snapshot);
    return request;
  }
}
