/*
 * Copyright (c) Huawei Technologies Co., Ltd. 2021-2021. All rights reserved.
 */

import Foundation

public class AGCCloudDBViewModel {
    
    public typealias CompletionHandler = (_ result: Any?, _ error: Error?) -> Void
    
    func openCloudDBZone2(cloudDB: AGConnectCloudDB, zoneConfig: AGCCloudDBZoneConfig, isAllowToCreate: Bool, completion: @escaping CompletionHandler) {
        cloudDB.openZone2(zoneConfig, allowCreate: isAllowToCreate) { (dbZone, error) in
            if let error = error {
                completion(nil, error)
            }
            completion(dbZone, nil)
        }
    }
    
    func openCloudDBZone(cloudDB: AGConnectCloudDB, zoneConfig: AGCCloudDBZoneConfig, isAllowToCreate: Bool, completion: @escaping CompletionHandler) {
        do {
            let dbZone = try cloudDB.openZone(zoneConfig, allowCreate: isAllowToCreate)
            completion(dbZone, nil)
        } catch {
            completion(nil, error)
        }
    }
    
    func setUserKey(cloudDB: AGConnectCloudDB, userKey: String, userReKey: String?, completion: @escaping CompletionHandler) {
        guard let userReKey = userReKey else {
            cloudDB.setUserKey(userKey, userRekey: nil) { error in
                if let error = error {
                    completion(nil, error)
                }else {
                    completion(nil, nil)
                }
            }
            return
        }
        cloudDB.setUserKey(userKey, userRekey: userReKey) { error in
            if let error = error {
                completion(nil, error)
            }else {
                completion(nil, nil)
            }
        }
    }
    
    func updateDataEncryptionKey(cloudDB: AGConnectCloudDB, completion: @escaping CompletionHandler) {
        cloudDB.updateDataEncryptionKey() { error in
            if let error = error {
                completion(nil, error)
            }else {
                completion(nil, nil)
            }
        }
    }
    
    func executeUpsert(dbZone: AGCCloudDBZone, instanceArray: [AGCCloudDBObject], completion: @escaping CompletionHandler) {
        dbZone.executeUpsert(instanceArray) { result, error in
            if let error = error {
                completion(nil, error)
            }else {
                completion(result, nil)
            }
        }
    }
    
    func executeDelete(dbZone: AGCCloudDBZone, instanceArray: [AGCCloudDBObject], completion: @escaping CompletionHandler) {
        dbZone.executeDelete(instanceArray) { result, error in
            if let error = error {
                completion(nil, error)
            }else {
                completion(result, nil)
            }
        }
    }
    
    func executeQuery(dbZone: AGCCloudDBZone, query: AGCCloudDBQuery, queryPolicy: AGCCloudDBQueryPolicy, completion: @escaping CompletionHandler) {
        dbZone.execute(query, policy: queryPolicy){ AGCCloudDBSnapshot,error in
            if let error = error {
                completion(nil, error)
            }
            if let snapshot = AGCCloudDBSnapshot {
                completion(snapshot, nil)
            }
        }
    }
    
    func executeQueryAverage(dbZone: AGCCloudDBZone, query: AGCCloudDBQuery, queryPolicy: AGCCloudDBQueryPolicy, fieldName: String, completion: @escaping CompletionHandler) {
        dbZone.executeQueryAverage(query, policy: queryPolicy, field: fieldName) { (v, e) in
            if let error = e {
                completion(nil, error)
            }else {
                completion(v, nil)
            }
        }
        dbZone.executeQueryAverage(query, policy: queryPolicy, field: fieldName) { value ,error in
            if let error = error {
                completion(nil, error)
            }else {
                completion(value, nil)
            }
        }
    }
    
    func executeSumQuery(dbZone: AGCCloudDBZone, query: AGCCloudDBQuery, queryPolicy: AGCCloudDBQueryPolicy, fieldName: String, completion: @escaping CompletionHandler) {
        dbZone.executeQuerySum(query, policy: queryPolicy, field: fieldName) { value ,error in
            if let error = error {
                completion(nil, error)
            }else {
                completion(value, nil)
            }
        }
    }
    
    func executeMaximumQuery(dbZone: AGCCloudDBZone, query: AGCCloudDBQuery, queryPolicy: AGCCloudDBQueryPolicy, fieldName: String, completion: @escaping CompletionHandler) {
        dbZone.executeQueryMaximum(query, policy: queryPolicy, field: fieldName) { value ,error in
            if let error = error {
                completion(nil, error)
            }else {
                completion(value, nil)
            }
        }
    }
    
    func executeMinimalQuery(dbZone: AGCCloudDBZone, query: AGCCloudDBQuery, queryPolicy: AGCCloudDBQueryPolicy, fieldName: String, completion: @escaping CompletionHandler) {
        dbZone.executeQueryMinimum(query, policy: queryPolicy, field: fieldName) { value ,error in
            if let error = error {
                completion(nil, error)
            }else {
                completion(value, nil)
            }
        }
    }
    
    func executeCountQuery(dbZone: AGCCloudDBZone, query: AGCCloudDBQuery, queryPolicy: AGCCloudDBQueryPolicy, fieldName: String, completion: @escaping CompletionHandler) {
        dbZone.executeQueryCount(query, policy: queryPolicy, field: fieldName) { value ,error in
            if let error = error {
                completion(nil, error)
            }else {
                completion(value, nil)
            }
        }
    }
    
    func executeQueryUnsynced(dbZone: AGCCloudDBZone, query: AGCCloudDBQuery, completion: @escaping CompletionHandler) {
        dbZone.executeQueryUnsynced(query) { AGCCloudDBSnapshot ,error in
            if let error = error {
                completion(nil, error)
            }
            if let snapshot = AGCCloudDBSnapshot {
                completion(snapshot, nil)
            }
        }
    }
    
    func subscribeSnapshot(dbZone: AGCCloudDBZone, query: AGCCloudDBQuery, queryPolicy: AGCCloudDBQueryPolicy, completion: @escaping CompletionHandler) -> AGCCloudDBListenerHandler? {
        return dbZone.subscribeSnapshot(with: query, policy: queryPolicy) { AGCCloudDBSnapshot ,error in
            if let error = error {
                completion(nil, error)
            }
            if let snapshot = AGCCloudDBSnapshot {
                completion(snapshot, nil)
            }
        }
    }
    
}
