// 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 XCTest
@testable import Syncbase
import enum Syncbase.Syncbase
import class Syncbase.Database
@testable import SyncbaseCore

let testQueue = dispatch_queue_create("SyncbaseQueue", DISPATCH_QUEUE_SERIAL)

class BasicDatabaseTests: XCTestCase {
  override class func setUp() {
    configureDb(disableUserdataSyncgroup: true, disableSyncgroupPublishing: true)
  }

  override class func tearDown() {
    Syncbase.shutdown()
  }

  func testDatabaseInit() {
    withDb { db in
      // Must be idempotent.
      try db.createIfMissing()
      try db.createIfMissing()
    }
  }

  func testCollection() {
    withDb { db in
      var collections = try db.collections()
      XCTAssertEqual(collections.count, 0)

      let collection = try db.createCollection(prefix: "testCollection")
      // Must be idempotent.
      try collection.createIfMissing()
      try collection.createIfMissing()
      collections = try db.collections()
      XCTAssertEqual(collections.count, 1)
      XCTAssertTrue(collection.collectionId.name.hasPrefix("testCollection"))
      XCTAssertGreaterThan(collection.collectionId.name.characters.count, "testCollection_".characters.count)
      // Should be empty.
      XCTAssertFalse(try collection.exists("a"))

      try collection.destroy()
      collections = try db.collections()
      XCTAssertEqual(collections.count, 0)
    }
  }

  // TODO(zinman): Add more unit tests.
}

class AdvertiseScanTests: XCTestCase {
  override class func setUp() {
    configureDb(disableUserdataSyncgroup: true, disableSyncgroupPublishing: true)
  }

  override class func tearDown() {
    Syncbase.shutdown()
  }

  func testAdvertise() {
    XCTAssertFalse(Syncbase.isAdvertisingPresenceInNeighborhood())
    withDb { _ in
      // Just a simple test of the API as a sanity check -- we'd need an integration test across
      // devices or multiple simulators to make sure advertising properly worked. Testing within one
      // process inside the simulator doesn't allow us to test Bluetooth (not possible anyway on the
      // simulator -- see https://forums.developer.apple.com/thread/47230 ) or mDNS across a real
      // network. Luckily the Go code has integration tests for discovery already.
      try Syncbase.startAdvertisingPresenceInNeighborhood()
      XCTAssertTrue(Syncbase.isAdvertisingPresenceInNeighborhood())
      try Syncbase.stopAdvertisingPresenceInNeighborhood()
      XCTAssertFalse(Syncbase.isAdvertisingPresenceInNeighborhood())

      try Syncbase.startAdvertisingPresenceInNeighborhood([User(alias: "zinman@google.com")])
      XCTAssertTrue(Syncbase.isAdvertisingPresenceInNeighborhood())
      try Syncbase.stopAdvertisingPresenceInNeighborhood()
      XCTAssertFalse(Syncbase.isAdvertisingPresenceInNeighborhood())
    }
  }

  func testScan() {
    withDb { _ in
      let handler = ScanNeighborhoodForUsersHandler(
        onFound: { user in
          XCTFail("Unexpected onFound user during unit test: \(user)")
        },
        onLost: { user in
          XCTFail("Unexpected onLost user during unit test: \(user)")
      })
      try Syncbase.startScanForUsersInNeighborhood(handler)

      Syncbase.neighborhoodScansMu.lock()
      XCTAssertEqual(Syncbase.neighborhoodScans.count, 1)
      Syncbase.neighborhoodScansMu.unlock()

      Syncbase.stopScanForUsersInNeighborhood(handler)

      Syncbase.neighborhoodScansMu.lock()
      XCTAssertEqual(Syncbase.neighborhoodScans.count, 0)
      Syncbase.neighborhoodScansMu.unlock()

      try Syncbase.startScanForUsersInNeighborhood(handler)
      Syncbase.stopAllScansForUsersInNeighborhood()
    }
  }
}

class UserdataTest: SyncgroupTest {
  func testUserdata() {
    withDb { db in
      let coreCollections = try db.coreDatabase.listCollections()
      XCTAssertEqual(coreCollections.count, 1)
      XCTAssertEqual(coreCollections[0].name, Syncbase.UserdataSyncgroupName)

      // Expect filtered from HLAPI.
      let collections = try db.collections()
      XCTAssertEqual(collections.count, 0)

      let coreSyncgroups = try db.coreDatabase.listSyncgroups()
      XCTAssertEqual(coreSyncgroups.count, 1)
      XCTAssertEqual(coreSyncgroups[0].name, Syncbase.UserdataSyncgroupName)

      // Expect filtered from HLAPI.
      let syncgroups = try db.syncgroups()
      XCTAssertEqual(syncgroups.count, 0)

      let verSpec = try db.coreDatabase.syncgroup(Syncbase.UserdataSyncgroupName).getSpec()
      XCTAssertEqual(verSpec.spec.collections.count, 1)

      // TODO(razvanm): Make the userdata syncgroup private.
      XCTAssertEqual(verSpec.spec.isPrivate, false)

      // Shouldn't crash unpacking.
      db.userdataCollection
    }
  }
}

class InviteUserdataFilteredTest: SyncgroupTest {
  func testUserdataFiltered() {
    withDb { db in
      db.addSyncgroupInviteHandler(SyncgroupInviteHandler(
        onInvite: { invite in
          XCTFail("Not expecting any invites")
        },
        onError: { err in
          XCTFail("Not expecting any errors: \(err)")
        }))
      NSThread.sleepForTimeInterval(0.1)
      db.removeAllSyncgroupInviteHandlers()
    }
  }
}

class InvitedSyncgroupsTest: SyncgroupTest {
  static let coreSyncgroupId = SyncbaseCore.Identifier(
    name: "someSg",
    blessing: "dev.v.io:o:some.apps.googleusercontent.com:someone@google.com")
  static let coreInvite = SyncbaseCore.SyncgroupInvite(
    syncgroupId: coreSyncgroupId,
    addresses: [""],
    blessingNames: [coreSyncgroupId.blessing])

  func testInvitedSyncgroupsNotIgnoredWhenNew() {
    withDb { db in

      var didGetInvite = false
      let handler = SyncgroupInviteHandler(
        onInvite: { invite in
          if invite.syncgroupId.name == InvitedSyncgroupsTest.coreSyncgroupId.name {
            didGetInvite = true
          }
        },
        onError: { err in
          XCTFail("Not expecting any errors: \(err)")
      })
      db.addSyncgroupInviteHandler(handler)
      let coreHandler = Database.syncgroupInviteHandlers[handler]
      coreHandler?.onInvite(InvitedSyncgroupsTest.coreInvite)
      XCTAssertTrue(didGetInvite)
      db.removeSyncgroupInviteHandler(handler)
    }
  }

  func testInvitedSyncgroupsIgnoredWhenJoined() {
    withDb { db in
      // We should get the invite when it's not in our userdata
      let coreInvite = SyncbaseCore.SyncgroupInvite(
        syncgroupId: InvitedSyncgroupsTest.coreSyncgroupId,
        addresses: [""],
        blessingNames: [InvitedSyncgroupsTest.coreSyncgroupId.blessing])
      var didGetInvite = false
      var handler = SyncgroupInviteHandler(
        onInvite: { invite in
          if invite.syncgroupId == Identifier(coreId: InvitedSyncgroupsTest.coreSyncgroupId) {
            didGetInvite = true
          }
        },
        onError: { err in
          XCTFail("Not expecting any errors: \(err)")
      })
      db.addSyncgroupInviteHandler(handler)
      var coreHandler = Database.syncgroupInviteHandlers[handler]
      coreHandler?.onInvite(coreInvite)
      XCTAssertTrue(didGetInvite)
      db.removeSyncgroupInviteHandler(handler)

      // Add it to userdata
      try Syncbase.addSyncgroupToUserdata(Identifier(coreId: InvitedSyncgroupsTest.coreSyncgroupId))

      // Now we shouldn't get it
      handler = SyncgroupInviteHandler(
        onInvite: { invite in
          XCTFail("Not expecting any invites: \(invite)")
        },
        onError: { err in
          XCTFail("Not expecting any errors: \(err)")
      })
      db.addSyncgroupInviteHandler(handler)
      coreHandler = Database.syncgroupInviteHandlers[handler]
      coreHandler?.onInvite(coreInvite)
      db.removeSyncgroupInviteHandler(handler)
    }
  }
}

class WatchSyncgroupTest: SyncgroupTest {
  func testAddingSyncgroup() {
    withDb { db in
      let initialSemaphore = dispatch_semaphore_create(0)
      let changeSemaphore = dispatch_semaphore_create(0)
      let sg1 = Identifier(coreId: SyncbaseCore.Identifier(name: "sg1", blessing: "..."))
      var didChange = false
      try db.addInternalUserdataWatchChangeHandler(handler: WatchChangeHandler(
        onInitialState: { _ in
          dispatch_semaphore_signal(initialSemaphore)
        },
        onChangeBatch: { changes in
          XCTAssertFalse(didChange)
          XCTAssertEqual(changes.count, 1)
          let change = changes.first!
          XCTAssertEqual(change.row, try? Syncbase.UserdataInternalSyncgroupPrefix + sg1.encode())
          XCTAssertEqual(change.changeType, WatchChange.ChangeType.Put)
          XCTAssertEqual(change.value, NSData())
          didChange = true
          dispatch_semaphore_signal(changeSemaphore)
        },
        onError: failOnNonContextError))
      if dispatch_semaphore_wait(initialSemaphore, secondsGCD(1)) != 0 {
        XCTFail("Timed out")
      }

      try Syncbase.addSyncgroupToUserdata(sg1)
      if dispatch_semaphore_wait(changeSemaphore, secondsGCD(1)) != 0 {
        XCTFail("Timed out")
      }
      XCTAssertEqual(didChange, true)
    }
  }

  func testWatchIgnoresInternalUserData() {
    withDb { db in
      var initialSemaphore = dispatch_semaphore_create(0)
      let changeSemaphore = dispatch_semaphore_create(0)
      // Only our own userdata additions should appear.
      try db.addWatchChangeHandler(handler: WatchChangeHandler(
        onInitialState: { changes in
          dispatch_semaphore_signal(initialSemaphore)
        },
        onChangeBatch: { changes in
          XCTAssertEqual(changes.count, 1)
          let change = changes[0]
          XCTAssertEqual(change.collectionId?.name, Syncbase.UserdataSyncgroupName)
          XCTAssertEqual(change.row, "testValue")
          dispatch_semaphore_signal(changeSemaphore)
        },
        onError: failOnNonContextError))
      if dispatch_semaphore_wait(initialSemaphore, secondsGCD(1)) != 0 {
        XCTFail("Timed out")
      }
      try db.userdataCollection.put("testValue", value: NSData())
      if dispatch_semaphore_wait(changeSemaphore, secondsGCD(1)) != 0 {
        XCTFail("Timed out")
      }
      db.removeAllWatchChangeHandlers()

      // Userdata only appears when explicitly asking for it.
      initialSemaphore = dispatch_semaphore_create(0)
      try db.addInternalUserdataWatchChangeHandler(
        handler: WatchChangeHandler(
          onInitialState: { changes in
            XCTAssertFalse(changes.isEmpty)
            for change in changes {
              XCTAssert(change.collectionId?.name == Syncbase.UserdataSyncgroupName)
              XCTAssert(change.row?.hasPrefix(Syncbase.UserdataInternalPrefix) ?? false)
            }
            dispatch_semaphore_signal(initialSemaphore)
          },
          onChangeBatch: { changes in
            XCTFail("Unexpected changes: \(changes)")
          },
          onError: failOnNonContextError))
      if dispatch_semaphore_wait(initialSemaphore, secondsGCD(1)) != 0 {
        XCTFail("Timed out")
      }
    }
  }
}
