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

import 'package:collection/collection.dart';

import '../../uint8list_ops.dart';
import 'converter.dart';

// Length of a bytelist, written on edge to value node.
// Bytelist content is: {1}{timetamp}, {timestamp} is 8 bytes long.
const _nodeValueSuffixLength = 9;
const _listEquality = ListEquality();

/// Type of child.
enum ChildType {
  /// Left child.
  left,

  /// Value stored in current node.
  value,

  /// Right child.
  right
}

/// Class to represent path from the root to some node in OrderedList implicit tree.
class OrderedListTreePath implements Comparable<OrderedListTreePath> {
  final Uint8List _data;

  /// Default constructor.
  OrderedListTreePath(this._data);

  /// Constructor from [parent] and additional parts of path.
  OrderedListTreePath.fromParent(
      OrderedListTreePath parent, List<Uint8List> labels)
      : this(concatListOfUint8Lists([parent._data]..addAll(labels)));

  /// Creates OrderedListTreePath corresponding to tree root.
  OrderedListTreePath.root() : this(Uint8List(_nodeValueSuffixLength));

  /// Checks if node is a child of a [parent].
  bool isDescendant(OrderedListTreePath parent) {
    if (_data.length <= parent._data.length) {
      return false;
    }
    int prefixLen = parent._data.length - _nodeValueSuffixLength;
    for (int i = 0; i < prefixLen; i++) {
      if (parent._data[i] != _data[i]) {
        return false;
      }
    }
    return true;
  }

  /// Returns path to parent implicit node, for value node.
  OrderedListTreePath parentPath() {
    // Remove appendix corresponding to value from path.
    return OrderedListTreePath(Uint8List.fromList(
        _data.getRange(0, _data.length - _nodeValueSuffixLength).toList()));
  }

  /// Returns OrderedListTreePath representing child of this.
  OrderedListTreePath getChild(
      ChildType side, Uint8List instanceId, Uint8List timestamp) {
    return OrderedListTreePath.fromParent(
        // ----------------
        // Path to implicit node:
        // 1. path to parent implicit node
        parentPath(),
        [
          // 2. direction ([left] or [right]).
          Uint8List.fromList([side.index]),
          // 3. id of current instance
          instanceId,
          // ----------------
          // Appendix for path to value:
          // 1. direction ([value])
          Uint8List.fromList([ChildType.value.index]),
          // 2. timestamp
          timestamp
        ]);
  }

  @override
  int compareTo(OrderedListTreePath p) {
    for (int i = 0; i < min(_data.length, p._data.length); i++) {
      if (_data[i] != p._data[i]) {
        return _data[i].compareTo(p._data[i]);
      }
    }
    return _data.length.compareTo(p._data.length);
  }

  @override
  int get hashCode => _listEquality.hash(_data);

  @override
  bool operator ==(dynamic p) => compareTo(p) == 0;
}

/// Converter for OrderedListTreePath.
class OrderedListTreePathConverter implements Converter<OrderedListTreePath> {
  /// Constructor.
  const OrderedListTreePathConverter();

  @override
  OrderedListTreePath get defaultValue =>
      OrderedListTreePath(Uint8List(0));

  @override
  OrderedListTreePath deserialize(final Uint8List x) =>
      OrderedListTreePath(x);

  @override
  Uint8List serialize(final OrderedListTreePath x) => x._data;
}

/// Public const instance of OrderedListTreePathConverter.
const OrderedListTreePathConverter orderedListTreePathConverter =
    OrderedListTreePathConverter();
