//
//  UsergridEntity.swift
//  UsergridSDK
//
//  Created by Robert Walsh on 7/21/15.
//
/*
 *
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  The ASF licenses this file to You
 * under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.  For additional information regarding
 * copyright in this work, please see the NOTICE file in the top level
 * directory of this distribution.
 *
 */

import Foundation
import CoreLocation

/**
`UsergridEntity` is the base class that contains a single Usergrid entity. 

`UsergridEntity` maintains a set of accessor properties for standard Usergrid schema properties (e.g. name, uuid), and supports helper methods for accessing any custom properties that might exist.
*/
open class UsergridEntity: NSObject, NSCoding {

    static private var subclassMappings: [String:UsergridEntity.Type] = [UsergridUser.USER_ENTITY_TYPE:UsergridUser.self,UsergridDevice.DEVICE_ENTITY_TYPE:UsergridDevice.self]

    // MARK: - Instance Properties -

    /// The property dictionary that stores the properties values of the `UsergridEntity` object.
    private var properties: [String : Any] {
        didSet {
            if let fileMetaData = properties.removeValue(forKey: UsergridFileMetaData.FILE_METADATA) as? [String:Any] {
                self.fileMetaData = UsergridFileMetaData(fileMetaDataJSON: fileMetaData)
            } else {
                self.fileMetaData = nil
            }
        }
    }

    /// The `UsergridAsset` that contains the asset data.
    internal(set) public var asset: UsergridAsset?

    /// The `UsergridFileMetaData` of this `UsergridEntity`.
    internal(set) public var fileMetaData : UsergridFileMetaData?

    /// Property helper method for the `UsergridEntity` objects `UsergridEntityProperties.type`.
    public var type: String { return self.getEntitySpecificProperty(.type) as! String }

    /// Property helper method for the `UsergridEntity` objects `UsergridEntityProperties.uuid`.
    public var uuid: String? { return self.getEntitySpecificProperty(.uuid) as? String }

    /// Property helper method for the `UsergridEntity` objects `UsergridEntityProperties.name`.
    public var name: String? { return self.getEntitySpecificProperty(.name) as? String }

    /// Property helper method for the `UsergridEntity` objects `UsergridEntityProperties.created`.
    public var created: Date? { return self.getEntitySpecificProperty(.created) as? Date }

    /// Property helper method for the `UsergridEntity` objects `UsergridEntityProperties.modified`.
    public var modified: Date? { return self.getEntitySpecificProperty(.modified) as? Date }

    /// Property helper method for the `UsergridEntity` objects `UsergridEntityProperties.location`.
    public var location: CLLocation? {
        get { return self.getEntitySpecificProperty(.location) as? CLLocation }
        set(newLocation) { self[UsergridEntityProperties.location.stringValue] = newLocation }
    }

    /// Property helper method to get the UUID or name of the `UsergridEntity`.
    public var uuidOrName: String? { return self.uuid ?? self.name }

    /// Tells you if this `UsergridEntity` has a type of `user`.
    public var isUser: Bool { return self is UsergridUser || self.type == UsergridUser.USER_ENTITY_TYPE }

    /// Tells you if there is an asset associated with this entity.
    public var hasAsset: Bool { return self.asset != nil || (self.fileMetaData?.contentLength ?? 0) > 0 }

    /// The JSON object value.
    public var jsonObjectValue : [String:Any] { return self.properties }

    /// The string value.
    public var stringValue : String { return NSString(data: try! JSONSerialization.data(withJSONObject: self.jsonObjectValue, options: .prettyPrinted), encoding: String.Encoding.utf8.rawValue) as! String }

    /// The description.
    open override var description : String {
        return "Properties of Entity: \(stringValue)."
    }

    /// The debug description.
    open override var debugDescription : String {
        return "Properties of Entity: \(stringValue)."
    }

    // MARK: - Initialization -

    /**
    Designated initializer for `UsergridEntity` objects

    - parameter type:         The type associated with the `UsergridEntity` object.
    - parameter name:         The optional name associated with the `UsergridEntity` object.
    - parameter propertyDict: The optional property dictionary that the `UsergridEntity` object will start out with.

    - returns: A new `UsergridEntity` object.
    */
    required public init(type:String, name:String? = nil, propertyDict:[String:Any]? = nil) {
        self.properties = propertyDict ?? [:]
        super.init()

        if self is UsergridUser {
            self.properties[UsergridEntityProperties.type.stringValue] = UsergridUser.USER_ENTITY_TYPE
        } else if self is UsergridDevice {
            self.properties[UsergridEntityProperties.type.stringValue] = UsergridDevice.DEVICE_ENTITY_TYPE
        } else {
            self.properties[UsergridEntityProperties.type.stringValue] = type
        }

        if let entityName = name {
            self.properties[UsergridEntityProperties.name.stringValue] = entityName
        }

        if let fileMetaData = self.properties.removeValue(forKey: UsergridFileMetaData.FILE_METADATA) as? [String:Any] {
            self.fileMetaData = UsergridFileMetaData(fileMetaDataJSON: fileMetaData)
        }
    }

    internal func copyInternalsFromEntity(_ entity:UsergridEntity) {
        self.properties = entity.properties
    }

    /**
     Used for custom mapping subclasses to a given `Usergrid` type.

     - parameter type:       The type of the `Usergrid` object.
     - parameter toSubclass: The subclass `UsergridEntity.Type` to map it to.
     */
    public static func mapCustomType(_ type:String,toSubclass:UsergridEntity.Type) {
        UsergridEntity.subclassMappings[type] = toSubclass
    }

    /**
    Class convenience constructor for creating `UsergridEntity` objects dynamically.

    - parameter jsonDict: A valid JSON dictionary which must contain at the very least a value for the `type` key.

    - returns: A `UsergridEntity` object provided that the `type` key within the dictionay exists. Otherwise nil.
    */
    public class func entity(jsonDict: [String:Any]) -> UsergridEntity? {
        guard let type = jsonDict[UsergridEntityProperties.type.stringValue] as? String
            else {
                return nil
        }

        let mapping = UsergridEntity.subclassMappings[type] ?? UsergridEntity.self
        return mapping.init(type: type, propertyDict: jsonDict)
    }

    /**
    Class convenience constructor for creating multiple `UsergridEntity` objects dynamically.

    - parameter entitiesJSONArray: An array which contains dictionaries that are used to create the `UsergridEntity` objects.

    - returns: An array of `UsergridEntity`.
    */
    public class func entities(jsonArray entitiesJSONArray: [[String:Any]]) -> [UsergridEntity] {
        var entityArray : [UsergridEntity] = []
        for entityJSONDict in entitiesJSONArray {
            if let entity = UsergridEntity.entity(jsonDict:entityJSONDict) {
                entityArray.append(entity)
            }
        }
        return entityArray
    }

    // MARK: - NSCoding -

    /**
    NSCoding protocol initializer.

    - parameter aDecoder: The decoder.

    - returns: A decoded `UsergridUser` object.
    */
    required public init?(coder aDecoder: NSCoder) {
        guard let properties = aDecoder.decodeObject(forKey: "properties") as? [String:Any]
            else {
                self.properties = [:]
                super.init()
                return nil
        }
        self.properties = properties
        self.fileMetaData = aDecoder.decodeObject(forKey: "fileMetaData") as? UsergridFileMetaData
        self.asset = aDecoder.decodeObject(forKey: "asset") as? UsergridAsset
        super.init()
    }

    /**
     NSCoding protocol encoder.

     - parameter aCoder: The encoder.
     */
    open func encode(with aCoder: NSCoder) {
        aCoder.encode(self.properties, forKey: "properties")
        aCoder.encode(self.fileMetaData, forKey: "fileMetaData")
        aCoder.encode(self.asset, forKey: "asset")
    }

    // MARK: - Property Manipulation -

    /**
    Subscript for the `UsergridEntity` class.
    
    - Example usage:
        ```
        let propertyValue = usergridEntity["propertyName"]
        usergridEntity["propertyName"] = propertyValue
        ```
    */
    public subscript(propertyName: String) -> Any? {
        get {
            if let entityProperty = UsergridEntityProperties.fromString(propertyName) {
                return self.getEntitySpecificProperty(entityProperty)
            } else {
                let propertyValue = self.properties[propertyName]
                if propertyValue is NSNull { // Let's just return nil for properties that have been removed instead of NSNull
                    return nil
                } else {
                    return propertyValue
                }
            }
        }
        set(propertyValue) {
            if let value = propertyValue {
                if let entityProperty = UsergridEntityProperties.fromString(propertyName) {
                    if entityProperty.isMutableForEntity(self) {
                        if entityProperty == .location {
                            if let location = value as? CLLocation {
                                properties[propertyName] = [ENTITY_LATITUDE:location.coordinate.latitude,
                                                            ENTITY_LONGITUDE:location.coordinate.longitude]
                            } else if let location = value as? CLLocationCoordinate2D {
                                properties[propertyName] = [ENTITY_LATITUDE:location.latitude,
                                                            ENTITY_LONGITUDE:location.longitude]
                            } else if let location = value as? [String:Double] {
                                if let lat = location[ENTITY_LATITUDE], let long = location[ENTITY_LONGITUDE] {
                                    properties[propertyName] = [ENTITY_LATITUDE:lat,
                                                                ENTITY_LONGITUDE:long]
                                }
                            }
                        } else {
                            properties[propertyName] = value
                        }
                    }
                } else {
                    properties[propertyName] = value
                }
            } else { // If the property value is nil we assume they wanted to remove the property.

                // We set the value for this property to Null so that when a PUT is performed on the entity the property will actually be removed from the Entity on Usergrid
                if let entityProperty = UsergridEntityProperties.fromString(propertyName){
                    if entityProperty.isMutableForEntity(self) {
                        properties[propertyName] = NSNull()
                    }
                } else {
                    properties[propertyName] = NSNull()
                }
            }
        }
    }

    /**
    Updates a properties value for the given property name.

    - parameter name:  The name of the property.
    - parameter value: The value to update to.
    */
    public func putProperty(_ name:String,value:Any?) {
        self[name] = value
    }

    /**
    Updates a set of properties that are within the given properties dictionary.

    - parameter properties: The property dictionary containing the properties names and values.
    */
    public func putProperties(_ properties:[String:Any]) {
        for (name,value) in properties {
            self.putProperty(name, value: value)
        }
    }

    /**
    Removes the property for the given property name.

    - parameter name: The name of the property.
    */
    public func removeProperty(_ name:String) {
        self[name] = nil
    }

    /**
    Removes the properties with the names within the propertyNames array

    - parameter propertyNames: An array of property names.
    */
    public func removeProperties(_ propertyNames:[String]) {
        for name in propertyNames {
            self.removeProperty(name)
        }
    }

    /**
    Appends the given value to the end of the properties current value.

    - parameter name:  The name of the property.
     - parameter value: The value or an array of values to append.
    */
    public func append(_ name:String, value:Any) {
        self.insertArray(name, values:value as? [Any] ?? [value], index: Int.max)
    }

    /**
    Inserts the given value at the given index within the properties current value.

    - parameter name:  The name of the property.
    - parameter index: The index to insert at.
    - parameter value: The value or an array of values to insert.
    */
    public func insert(_ name:String, value:Any, index:Int = 0) {
        self.insertArray(name, values:value as? [Any] ?? [value], index: index)
    }

    /**
    Inserts an array of property values at a given index within the properties current value.

    - parameter name:   The name of the property
    - parameter index:  The index to insert at.
    - parameter values: The values to insert.
    */
    private func insertArray(_ name:String,values:[Any], index:Int = 0) {
        if let propertyValue = self[name] {
            if let arrayValue = propertyValue as? [Any] {
                var arrayOfValues = arrayValue
                if  index > arrayValue.count {
                    arrayOfValues.append(contentsOf: values)
                } else {
                    arrayOfValues.insert(contentsOf: values, at: index)
                }
                self[name] = arrayOfValues
            } else {
                if index > 0 {
                    self[name] = [propertyValue] + values
                } else {
                    self[name] = values + [propertyValue]
                }
            }
        } else {
            self[name] = values
        }
    }

    /**
    Removes the last value of the properties current value.

    - parameter name: The name of the property.
    */
    public func pop(_ name:String) {
        if let arrayValue = self[name] as? [Any] , arrayValue.count > 0 {
            var arrayOfValues = arrayValue
            arrayOfValues.removeLast()
            self[name] = arrayOfValues
        }
    }

    /**
    Removes the first value of the properties current value.

    - parameter name: The name of the property.
    */
    public func shift(_ name:String) {
        if let arrayValue = self[name] as? [Any] , arrayValue.count > 0 {
            var arrayOfValues = arrayValue
            arrayOfValues.removeFirst()
            self[name] = arrayOfValues
        }
    }

    private func getEntitySpecificProperty(_ entityProperty: UsergridEntityProperties) -> Any? {
        var propertyValue: Any? = nil
        switch entityProperty {
            case .uuid,.type,.name :
                propertyValue = self.properties[entityProperty.stringValue]
            case .created,.modified :
                if let milliseconds = self.properties[entityProperty.stringValue] as? Int {
                    propertyValue = Date(milliseconds: milliseconds.description)
                }
            case .location :
                if let locationDict = self.properties[entityProperty.stringValue] as? [String:Double], let lat = locationDict[ENTITY_LATITUDE], let long = locationDict[ENTITY_LONGITUDE] {
                    propertyValue = CLLocation(latitude: lat, longitude: long)
                }
            }
        return propertyValue
    }

    // MARK: - CRUD Convenience Methods -

    /**
    Performs a GET on the `UsergridEntity` using the shared instance of `UsergridClient`.

    - parameter completion: An optional completion block that, if successful, will contain the reloaded `UsergridEntity` object.
    */
    public func reload(_ completion: UsergridResponseCompletion? = nil) {
        self.reload(Usergrid.sharedInstance, completion: completion)
    }

    /**
    Performs a GET on the `UsergridEntity`.

    - parameter client:     The client to use when reloading.
    - parameter completion: An optional completion block that, if successful, will contain the reloaded `UsergridEntity` object.
    */
    public func reload(_ client:UsergridClient, completion: UsergridResponseCompletion? = nil) {
        guard let uuidOrName = self.uuidOrName
            else {
                completion?(UsergridResponse(client: client, errorName: "Entity cannot be reloaded.", errorDescription: "Entity has neither an UUID or name specified."))
                return
        }

        client.GET(self.type, uuidOrName: uuidOrName) { response in
            if let responseEntity = response.entity {
                self.copyInternalsFromEntity(responseEntity)
            }
            completion?(response)
        }
    }

    /**
    Performs a PUT (or POST if no UUID is found) on the `UsergridEntity` using the shared instance of `UsergridClient`.

    - parameter completion: An optional completion block that, if successful, will contain the updated/saved `UsergridEntity` object.
    */
    public func save(_ completion: UsergridResponseCompletion? = nil) {
        self.save(Usergrid.sharedInstance, completion: completion)
    }

    /**
    Performs a PUT (or POST if no UUID is found) on the `UsergridEntity`.

    - parameter client:     The client to use when saving.
    - parameter completion: An optional completion block that, if successful, will contain the updated/saved `UsergridEntity` object.
    */
    public func save(_ client:UsergridClient, completion: UsergridResponseCompletion? = nil) {
        if let _ = self.uuid { // If UUID exists we PUT otherwise POST
            client.PUT(self) { response in
                if let responseEntity = response.entity {
                    self.copyInternalsFromEntity(responseEntity)
                }
                completion?(response)
            }
        } else {
            client.POST(self) { response in
                if let responseEntity = response.entity {
                    self.copyInternalsFromEntity(responseEntity)
                }
                completion?(response)
            }
        }
    }

    /**
    Performs a DELETE on the `UsergridEntity` using the shared instance of the `UsergridClient`.

    - parameter completion: An optional completion block.
    */
    public func remove(_ completion: UsergridResponseCompletion? = nil) {
        self.remove(Usergrid.sharedInstance, completion: completion)
    }

    /**
    Performs a DELETE on the `UsergridEntity`.

    - parameter client:     The client to use when removing.
    - parameter completion: An optional completion block.
    */
    public func remove(_ client:UsergridClient, completion: UsergridResponseCompletion? = nil) {
        client.DELETE(self, completion: completion)
    }

    // MARK: - Asset Management -

    /**
    Uploads the given `UsergridAsset` and the data within it and creates an association between this `UsergridEntity` with the given `UsergridAsset` using the shared instance of `UsergridClient`.

    - parameter asset:      The `UsergridAsset` object to upload.
    - parameter progress:   An optional progress block to keep track of upload progress.
    - parameter completion: An optional completion block.
    */
    public func uploadAsset(_ asset:UsergridAsset, progress:UsergridAssetRequestProgress? = nil, completion:UsergridAssetUploadCompletion? = nil) {
        self.uploadAsset(Usergrid.sharedInstance, asset: asset, progress: progress, completion: completion)
    }

    /**
    Uploads the given `UsergridAsset` and the data within it and creates an association between this `UsergridEntity` with the given `UsergridAsset`.

    - parameter client:     The client to use when uploading.
    - parameter asset:      The `UsergridAsset` object to upload.
    - parameter progress:   An optional progress block to keep track of upload progress.
    - parameter completion: An optional completion block.
    */
    public func uploadAsset(_ client:UsergridClient, asset:UsergridAsset, progress:UsergridAssetRequestProgress? = nil, completion:UsergridAssetUploadCompletion? = nil) {
        client.uploadAsset(self, asset: asset, progress:progress, completion:completion)
    }

    /**
    Downloads the `UsergridAsset` that is associated with this `UsergridEntity` using the shared instance of `UsergridClient`.

    - parameter contentType: The content type of the data to load.
    - parameter progress:    An optional progress block to keep track of download progress.
    - parameter completion:  An optional completion block.
    */
    public func downloadAsset(_ contentType:String, progress:UsergridAssetRequestProgress? = nil, completion:UsergridAssetDownloadCompletion? = nil) {
        self.downloadAsset(Usergrid.sharedInstance, contentType: contentType, progress: progress, completion: completion)
    }

    /**
    Downloads the `UsergridAsset` that is associated with this `UsergridEntity`.

    - parameter client:      The client to use when uploading.
    - parameter contentType: The content type of the data to load.
    - parameter progress:    An optional progress block to keep track of download progress.
    - parameter completion:  An optional completion block.
    */
    public func downloadAsset(_ client:UsergridClient, contentType:String, progress:UsergridAssetRequestProgress? = nil, completion:UsergridAssetDownloadCompletion? = nil) {
        client.downloadAsset(self, contentType: contentType, progress:progress, completion: completion)
    }

    // MARK: - Connection Management -

    /**
    Creates a relationship between this `UsergridEntity` and the given entity using the shared instance of `UsergridClient`.

    - parameter relationship: The relationship type.
    - parameter toEntity:     The entity to connect.
    - parameter completion:   An optional completion block.
    */
    public func connect(_ relationship:String, toEntity:UsergridEntity, completion: UsergridResponseCompletion? = nil) {
        self.connect(Usergrid.sharedInstance, relationship: relationship, toEntity: toEntity, completion: completion)
    }

    /**
    Creates a relationship between this `UsergridEntity` and the given entity.

    - parameter client:       The client to use when connecting.
    - parameter relationship: The relationship type.
    - parameter toEntity:     The entity to connect.
    - parameter completion:   An optional completion block.
    */
    public func connect(_ client:UsergridClient, relationship:String, toEntity:UsergridEntity, completion: UsergridResponseCompletion? = nil) {
        client.connect(self, relationship: relationship, to: toEntity, completion: completion)
    }

    /**
    Removes a relationship between this `UsergridEntity` and the given entity using the shared instance of `UsergridClient`.

    - parameter relationship: The relationship type.
    - parameter fromEntity:   The entity to disconnect.
    - parameter completion:   An optional completion block.
    */
    public func disconnect(_ relationship:String, fromEntity:UsergridEntity, completion: UsergridResponseCompletion? = nil) {
        self.disconnect(Usergrid.sharedInstance, relationship: relationship, fromEntity: fromEntity, completion: completion)
    }

    /**
    Removes a relationship between this `UsergridEntity` and the given entity.

    - parameter client:       The client to use when disconnecting.
    - parameter relationship: The relationship type.
    - parameter fromEntity:   The entity to disconnect.
    - parameter completion:   An optional completion block.
    */
    public func disconnect(_ client:UsergridClient, relationship:String, fromEntity:UsergridEntity, completion: UsergridResponseCompletion? = nil) {
        client.disconnect(self, relationship: relationship, from: fromEntity, completion: completion)
    }

    /**
    Gets the `UsergridEntity` objects, if any, which are connected via the relationship using the shared instance of `UsergridClient`.

    - parameter direction:      The direction of the connection.
    - parameter relationship:   The relationship type.
    - parameter query:          The optional query.
    - parameter completion:     An optional completion block.
    */
    public func getConnections(_ direction:UsergridDirection, relationship:String, query:UsergridQuery? = nil, completion:UsergridResponseCompletion? = nil) {
        self.getConnections(Usergrid.sharedInstance, direction: direction, relationship: relationship, query: query, completion: completion)
    }

    /**
    Gets the `UsergridEntity` objects, if any, which are connected via the relationship.

    - parameter client:       The client to use when getting the connected `UsergridEntity` objects.
    - parameter direction:    The direction of the connection.
    - parameter relationship: The relationship type.
    - parameter query:        The optional query.
    - parameter completion:   An optional completion block.
    */
    public func getConnections(_ client:UsergridClient, direction:UsergridDirection, relationship:String, query:UsergridQuery? = nil, completion:UsergridResponseCompletion? = nil) {
        client.getConnections(direction, entity: self, relationship: relationship, query:query, completion: completion)
    }

    // MARK: - Helper methods -

    /**
     Determines if the two `UsergridEntity` objects are equal.  i.e. they have the same non nil uuidOrName.

     - parameter entity: The entity to check.

     - returns: If the two `UsergridEntity` objects are equal.  i.e. they have the same non nil uuidOrName.
     */
    public func isEqualToEntity(_ entity: UsergridEntity?) -> Bool {
        guard let selfUUID = self.uuidOrName,
              let entityUUID = entity?.uuidOrName
            else {
                return false
        }
        return selfUUID == entityUUID
    }
}
