// Copyright 2015 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

public enum PromiseErrors<ResolveType>: ErrorType {
  case AlreadyResolved(existingObj:ResolveType)
  case AlreadyRejected(existingErr:ErrorType?)
  case Timeout
}

public class Promise<ResolveType> : Lockable {
  private var resolveCallbacks:[(dispatch_queue_t?, ResolveType->())]? = nil
  private var rejectCallbacks:[(dispatch_queue_t?, ErrorType?->())]? = nil
  private var alwaysCallbacks:[(dispatch_queue_t?, Resolution<ResolveType>->())]? = nil
  private let resolutionSemaphore = dispatch_semaphore_create(0)
  
  internal var status: Resolution<ResolveType> = Resolution.Pending {
    didSet {
      updatedStatus()
    }
  }
  
  public init() { }
  
  public convenience init(resolved obj: ResolveType) {
    self.init()
    status = Resolution.Resolved(obj: obj)
  }

  public convenience init(rejected err: ErrorType?) {
    self.init()
    status = Resolution.Rejected(err: err)
  }
  
  // Resolve/reject
  public func resolve(obj:ResolveType) throws {
    objc_sync_enter(self)
    defer { objc_sync_exit(self) }
    switch (status) {
    case .Rejected(let err): throw PromiseErrors<ResolveType>.AlreadyRejected(existingErr: err)
    case .Resolved(let obj): throw PromiseErrors<ResolveType>.AlreadyResolved(existingObj: obj)
    case .Pending: status = Resolution.Resolved(obj: obj)
    }
  }
  
  public func reject(err:ErrorType?) throws {
    objc_sync_enter(self)
    defer { objc_sync_exit(self) }
    switch (status) {
    case .Rejected(let err): throw PromiseErrors<ResolveType>.AlreadyRejected(existingErr: err)
    case .Resolved(let obj): throw PromiseErrors<ResolveType>.AlreadyResolved(existingObj: obj)
    case .Pending: status = Resolution.Rejected(err: err)
    }
  }

  // Chain/handle state
  public func onResolve(on queue: dispatch_queue_t?=dispatch_get_main_queue(),
                        _ callback:ResolveType->()) -> Promise<ResolveType> {
    objc_sync_enter(self)
    defer { objc_sync_exit(self) }
    switch(status) {
    case .Resolved(let obj): dispatch_maybe_async(queue, block: { callback(obj) })
    case .Rejected: break
    case .Pending:
      if resolveCallbacks == nil {
        resolveCallbacks = []
      }
      resolveCallbacks!.append((queue, callback))
    }
                          
    return self
  }
  
  public func onReject(on queue: dispatch_queue_t?=dispatch_get_main_queue(),
                       _ callback:ErrorType?->()) -> Promise<ResolveType> {
    objc_sync_enter(self)
    defer { objc_sync_exit(self) }
    switch(status) {
    case .Resolved: break
    case .Rejected(let err): dispatch_maybe_async(queue, block: { callback(err) })
    case .Pending:
      if rejectCallbacks == nil {
        rejectCallbacks = []
      }
      rejectCallbacks!.append((queue, callback))
    }
    return self
  }
  
  public func always(on queue: dispatch_queue_t?=dispatch_get_main_queue(),
                     _ callback:Resolution<ResolveType>->()) -> Promise<ResolveType> {
    objc_sync_enter(self)
    defer { objc_sync_exit(self) }
    let s = status
    switch(s) {
    case .Pending:
      if alwaysCallbacks == nil {
        alwaysCallbacks = []
      }
      alwaysCallbacks!.append((queue, callback))
    default: dispatch_maybe_async(queue, block: { callback(s) })
    }
    return self
  }
  
  public func await(timeout: NSTimeInterval?=nil) throws -> Resolution<ResolveType> {
    switch (status) {
    case .Pending:
      if let timeout = timeout {
        if dispatch_semaphore_wait(resolutionSemaphore, dispatch_time_t.fromNSTimeInterval(timeout)) != 0 {
          throw PromiseErrors<ResolveType>.Timeout
        }
      } else {
        dispatch_semaphore_wait(resolutionSemaphore, DISPATCH_TIME_FOREVER)
      }
    default: break
    }
    return status
  }
  
  // Changing states
  internal func updatedStatus() {
    // Do reject/resolve callbacks, then always callbacks
    let s = status
    switch (s) {
    case .Pending: return // Don't do anything, but this shouldn't happen
    case .Rejected(let err):
      guard let callbacks = rejectCallbacks else { break }
      for (queue, callback) in callbacks {
        dispatch_maybe_async(queue) {
          callback(err)
        }
      }
    case .Resolved(let obj):
      guard let callbacks = resolveCallbacks else { break }
      for (queue, callback) in callbacks {
        dispatch_maybe_async(queue) {
          callback(obj)
        }
      }
    }
    
    defer { dispatch_semaphore_signal(resolutionSemaphore) }
    guard let callbacks = alwaysCallbacks else { return }
    for (queue, callback) in callbacks {
      dispatch_maybe_async(queue) {
        callback(s)
      }
    }
  }
}

public class ResolvedPromise<ResolveType>: Promise<ResolveType> {
  var resolvedObj:ResolveType
  
  override private init() {
    fatalError("Cannot init this way")
  }
  
  public convenience init(_ resolved: ResolveType) {
    self.init(resolved: resolved)
    self.resolvedObj = resolved
    dispatch_semaphore_signal(resolutionSemaphore)
  }
  
  override public func onResolve(on queue: dispatch_queue_t?=dispatch_get_main_queue(),
    _ callback:ResolveType->()) -> Promise<ResolveType> {
      dispatch_maybe_async(queue, block: { callback(self.resolvedObj) })
      return self
  }

  override public func always(on queue: dispatch_queue_t?=dispatch_get_main_queue(),
    _ callback:Resolution<ResolveType>->()) -> Promise<ResolveType> {
      dispatch_maybe_async(queue, block: { callback(self.status) })
      return self
  }
  
  override public func resolve(obj:ResolveType) throws {
    throw PromiseErrors<ResolveType>.AlreadyResolved(existingObj: resolvedObj)
  }

  override public func reject(err:ErrorType?) throws {
    throw PromiseErrors<ResolveType>.AlreadyResolved(existingObj: resolvedObj)
  }
}

public class RejectedPromise: Promise<Void> {
  var err:ErrorType?
  
  override private init() {
    fatalError("Cannot init this way")
  }
  
  public convenience init(_ error: ErrorType?) {
    self.init(rejected: error)
    self.err = error
    dispatch_semaphore_signal(resolutionSemaphore)
  }
  
  override public func onReject(on queue: dispatch_queue_t?, _ callback: ErrorType? -> ()) -> Promise<Void> {
    dispatch_maybe_async(queue, block: { callback(self.err) })
    return self
  }

  override public func always(on queue: dispatch_queue_t?=dispatch_get_main_queue(),
    _ callback:Resolution<Void>->()) -> Promise<Void> {
    dispatch_maybe_async(queue, block: { callback(self.status) })
    return self
  }
  
  override public func resolve(obj:Void) throws {
    throw PromiseErrors<Void>.AlreadyRejected(existingErr: self.err)
  }

  override public func reject(err:ErrorType?) throws {
    throw PromiseErrors<Void>.AlreadyRejected(existingErr: self.err)
  }
}

public enum Resolution<ResolveType> {
  case Pending
  case Resolved(obj:ResolveType)
  case Rejected(err:ErrorType?)
}

/// Quick initializers for already resolved/rejected constructors
public extension Promise {
  public static func resolved() -> Promise<Void> { return Promise<Void>(resolved: ()) }
  public static func resolved(obj:ResolveType) -> Promise<ResolveType> { return ResolvedPromise(obj) }
  public static func rejected(err:ErrorType? = nil) -> Promise<Void> { return RejectedPromise(err) }
}

/// Chaining API
public extension Promise {
  func then<T>(on queue: dispatch_queue_t?=dispatch_get_main_queue(),
               _ callback:ResolveType throws ->T) -> Promise<T> {
    let p = Promise<T>()
    onResolve(on: queue) { obj in
      do {
        let transformed = try callback(obj)
        try p.resolve(transformed)
      } catch let e {
        try! p.reject(e)
      }
    }
    onReject(on: queue) { err in
      try! p.reject(err)
    }
    return p
  }
 
  /// Specialize then for when it returns another Promise to hook onto that automatically
  func then<T>(on queue: dispatch_queue_t?=dispatch_get_main_queue(),
               _ callback:ResolveType throws ->Promise<T>) -> Promise<T> {
    let p = Promise<T>()
                
    onResolve(on: queue) { obj in
      do {
        let newPromise = try callback(obj)
        newPromise.onResolve(on: queue) { obj in
          do {
            try p.resolve(obj)
          } catch let e {
            try! p.reject(e)
          }
        }
        newPromise.onReject(on: queue) { err in
          try! p.reject(err)
        }
      } catch let e {
        try! p.reject(e)
      }
    }
                
    onReject(on: queue) { err in
      try! p.reject(err)
    }
    return p
  }
  
  func thenInBackground<T>(callback:ResolveType throws ->T) -> Promise<T> {
    return then(on: dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), callback)
  }

  func thenOnSameThread<T>(callback:ResolveType throws ->T) -> Promise<T> {
    return then(on: nil, callback)
  }
}

/// Visibility into status
public extension Promise {
  public func isPending() -> Bool {
    switch (status) {
    case .Pending: return true
    default: return false
    }
  }
  
  public func isResolved() -> Bool {
    switch (status) {
    case .Resolved: return true
    default: return false
    }
  }
  
  public func isRejected() -> Bool {
    switch (status) {
    case .Rejected: return true
    default: return false
    }
  }
}

/// Utilities for timeout functionality
public extension Promise {
  /// Timeout (reject) if not resolved or rejected within a given timeframe
  public func rejectAfterDelay(on queue:dispatch_queue_t=dispatch_get_main_queue(), delay:NSTimeInterval) {
    dispatch_after_delay(delay, queue: queue, block: {
      switch (self.status) {
      case .Pending:
        do { try self.reject(PromiseErrors<ResolveType>.Timeout) }
        catch { }
      default: break
      }
    })
  }
}