// Copyright 2016 The Vanadium 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 Foundation
import SyncbaseCore

/// CollectionRowPattern contains SQL LIKE-style glob patterns ('%' and '_'
/// wildcards, '\' as escape character) for matching rows and collections by
/// name components. It is used by the Database.watch API.
public struct CollectionRowPattern {
  /// WildCard matches everything.
  public static var Everything = CollectionRowPattern(
    collectionName: Wildcard, collectionBlessing: Wildcard, rowKey: Wildcard)

  public static var Wildcard = "%"

  /// collectionName is a SQL LIKE-style glob pattern ('%' and '_' wildcards, '\' as escape
  /// character) for matching collections. May not be empty.
  public let collectionName: String

  /// The blessing for collections.
  public let collectionBlessing: String

  /// rowKey is a SQL LIKE-style glob pattern ('%' and '_' wildcards, '\' as escape character)
  /// for matching rows. If empty then only the collectionId pattern is matched and NO row events
  /// are returned.
  public let rowKey: String?

  public init(collectionName: String = Wildcard, collectionBlessing: String = Wildcard, rowKey: String? = Wildcard) {
    self.collectionName = collectionName
    self.collectionBlessing = collectionBlessing
    self.rowKey = rowKey
  }

  public init(collectionId: Identifier, rowKey: String? = Wildcard) {
    self.collectionName = collectionId.name
    self.collectionBlessing = collectionId.blessing
    self.rowKey = rowKey
  }

  func toCore() -> SyncbaseCore.CollectionRowPattern {
    return SyncbaseCore.CollectionRowPattern(
      collectionName: collectionName,
      collectionBlessing: collectionBlessing,
      rowKey: rowKey)
  }
}

/// ResumeMarker provides a compact representation of all the messages that
/// have been received by the caller for the given Watch call. It is not
/// something that you would ever generate; it is always provided to you
/// in a WatchChange.
public typealias ResumeMarker = NSData

/// Describes a change to a database.
public class WatchChange: CustomStringConvertible {
  public enum EntityType: Int {
    // Root is filtered out of the higher-level API.
    case Collection = 1
    case Row = 2
  }

  public enum ChangeType: Int {
    case Put
    case Delete
  }

  /// EntityType is the type of the entity - Root, Collection, or Row.
  public let entityType: EntityType

  /// Collection is the id of the collection that was changed or contains the
  /// changed row. Is nil if EntityType is not Collection or Row.
  public let collectionId: Identifier?

  /// Row is the key of the changed row. Nil if EntityType is not Row.
  public let row: String?

  /// ChangeType describes the type of the change, depending on the EntityType:
  ///
  /// **EntityRow:**
  ///
  /// - PutChange: the row exists in the collection, and Value can be called to
  /// obtain the new value for this row.
  ///
  /// - DeleteChange: the row was removed from the collection.
  ///
  /// **EntityCollection:**
  ///
  /// - PutChange: the collection exists, and CollectionInfo can be called to
  /// obtain the collection info.
  ///
  /// - DeleteChange: the collection was destroyed.
  ///
  /// **EntityRoot:**
  ///
  /// - PutChange: appears as the first (possibly only) change in the initial
  /// state batch, only if watching from an empty ResumeMarker. This is the
  /// only situation where an EntityRoot appears.
  public let changeType: ChangeType

  /// value is the new value for the row for EntityRow PutChanges, an encoded
  /// StoreChangeCollectionInfo value for EntityCollection PutChanges, or nil
  /// otherwise.
  public let value: NSData?

  /// ResumeMarker provides a compact representation of all the messages that
  /// have been received by the caller for the given Watch call.
  /// This marker can be provided in the Request message to allow the caller
  /// to resume the stream watching at a specific point without fetching the
  /// initial state.
  public let resumeMarker: ResumeMarker?

  /// FromSync indicates whether the change came from sync. If FromSync is false,
  /// then the change originated from the local device.
  public let isFromSync: Bool

  /// If true, this WatchChange is followed by more WatchChanges that are in the
  /// same batch as this WatchChange.
  public let isContinued: Bool

  init(coreChange: SyncbaseCore.WatchChange) {
    self.entityType = EntityType(rawValue: coreChange.entityType.rawValue)!
    if let coreCollectionId = coreChange.collectionId {
      self.collectionId = Identifier(coreId: coreCollectionId)
    } else {
      self.collectionId = nil
    }
    self.row = coreChange.row
    self.changeType = ChangeType(rawValue: coreChange.changeType.rawValue)!
    self.value = coreChange.value
    self.resumeMarker = coreChange.resumeMarker
    self.isFromSync = coreChange.isFromSync
    self.isContinued = coreChange.isContinued
  }

  public var description: String {
    var valueDesc = "<nil>"
    if let v = value {
      if v.length > 1024 {
        valueDesc = "<\(v.length) bytes>"
      } else if let str = String(data: v, encoding: NSUTF8StringEncoding) {
        valueDesc = str
      } else {
        valueDesc = v.description
      }
    }
    return "[Syncbase.WatchChange entityType=\(entityType) changeType=\(changeType) " +
      "collectionId=\(collectionId) row=\(row) isFromSync=\(isFromSync) isContinued=\(isContinued) " +
      "value=\(valueDesc) ]"
  }
}