// 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 XCTest
import VanadiumCore

enum TestErrors : ErrorType {
  case SomeError
  case SomeOtherError
}

class PromiseTests: XCTestCase {
  func testBasicResolution() {
    var alwaysRan = false
    let p = Promise<Int>()
      .onResolve { obj in XCTAssertEqual(obj, 5) }
      .onReject { err in XCTFail("Shouldn't have gotten \(err)") }
      .always { status in
        switch (status) {
        case .Pending: XCTFail("Can't get pending in always")
        case .Rejected(let e): XCTFail("Shouldn't have gotten \(e)")
        case .Resolved: alwaysRan = true
        }
      }
    try! p.resolve(5)
    XCTAssertTrue(alwaysRan)
    
    var ranNow = false
    p.onResolve { obj in
      ranNow = true
    }
    XCTAssertTrue(ranNow)
  }

  func testBasicRejection() {
    var alwaysRan = false
    let p = Promise<Int>()
      .onResolve { obj in XCTFail("Shouldn't have gotten \(obj)") }
      .onReject { err in
        guard let e = err else { XCTFail("Invalid nil error"); return }
        switch(e) {
        case TestErrors.SomeError: break
        default: XCTFail("Shouldn't have gotten this error \(e)")
        }
      }
      .always { status in
        switch (status) {
        case .Pending: XCTFail("Can't get pending in always")
        case .Rejected: alwaysRan = true
        case .Resolved(let o): XCTFail("Shouldn't have gotten \(o)")
        }
      }
    try! p.reject(TestErrors.SomeError)
    XCTAssertTrue(alwaysRan)

    var ranNow = false
    p.onReject { err in
      ranNow = true
    }
    XCTAssertTrue(ranNow)
  }

  func testResolutionDoesntRunOnResolve() {
    let p = Promise<Int>()
    p.onResolve { obj in
      XCTFail("Shouldn't have gotten \(obj)")
    }
    try! p.reject(TestErrors.SomeError)
  }
  
  func testRejectionDoesntRunOnResolve() {
    let p = Promise<Int>()
    p.onReject { err in
      XCTFail("Shouldn't have gotten \(err)")
    }
    try! p.resolve(5)
  }
  
  func testThenTransforms() {
    let p = Promise<Int>()
    try! p.resolve(5)
    
    var finalResult:String = ""
    p.then { obj -> String in
      XCTAssertEqual(obj, 5)
      return "hello"
    }.onResolve { obj in
      XCTAssertEqual(obj, "hello")
      finalResult = obj
    }
    XCTAssertEqual(finalResult, "hello")
  }

  func testThenPropagatesError() {
    let p = Promise<Int>()
    
    var didReject = false
    p.then { obj -> String in
      XCTAssertEqual(obj, 5)
      return "hello"
    }.onReject { _ in
      didReject = true
    }
    try! p.reject(TestErrors.SomeError)
    XCTAssertTrue(didReject)
  }
  
  func testThenReturningPromiseWorks() {
    let p = Promise<Int>()
    let bgQueue = dispatch_get_global_queue(QOS_CLASS_BACKGROUND, 0)
    let finalP = p.then(on: bgQueue) { x -> Promise<Int> in
      let newP = Promise<Int>()
      dispatch_async(bgQueue) {
        try! newP.resolve(x + 10)
      }
      return newP
    }
    
    try! p.resolve(5)
    let finalStatus = try! finalP.await()
    switch (finalStatus) {
    case .Resolved(let v): XCTAssertEqual(v, 15)
    default: XCTFail("Supposed to be resolved")
    }
  }
}
