//
//  Console.swift
//  Zockerhoehle
//
//  Created by Julian-Steffen Müller on 12.09.18.
//  Copyright © 2018 Julian-Steffen Müller. All rights reserved.
//

import Foundation

typealias FlockeEntryID = String

class FlockeEntry : Codable {
    let id : FlockeEntryID
    let isDeleted : Bool
    let name : String
    let createdOn : String
    let changedOn : String
    let content : [String : Any]
    var iconAttachment : Attachment?
    var parents : [FlockeEntryID]
    
    init (entry : FlockeEntry) {
        self.id = entry.id
        self.isDeleted = entry.isDeleted
        self.name = entry.name
        self.createdOn = entry.createdOn
        self.changedOn = entry.changedOn
        self.content = entry.content
        self.iconAttachment = entry.iconAttachment
        self.parents = entry.parents
    }
    
    required init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
        
        id = try container.decode(String.self, forKey: .id)
        isDeleted = try container.decode(Bool.self, forKey: .isDeleted)
        name = try container.decode(String.self, forKey: .name)
        createdOn = try container.decode(String.self, forKey: .createdOn)
        changedOn = try container.decode(String.self, forKey: .changedOn)
        
        parents  = try container.decode([FlockeEntryID].self, forKey: .parents)
        
        do {
            content = try container.decode([String : Any].self, forKey: .content)
        }catch{
            content = [:]
        }
        
        do {
            let attachmentContainer = try container.nestedContainer(keyedBy: CodingKeys.self, forKey: .attachments)
            
            iconAttachment = try? attachmentContainer.decode(Attachment.self, forKey: .icon)
        }catch {
            iconAttachment = nil
        }
    }
    
    func encode(to encoder: Encoder) throws {
        var container = encoder.container(keyedBy: CodingKeys.self)
        
        try container.encode(self.id, forKey: .id)
        try container.encode(self.isDeleted, forKey: .isDeleted)
        try container.encode(self.name, forKey: .name)
        try container.encode(self.createdOn, forKey: .createdOn)
        try container.encode(self.changedOn, forKey: .changedOn)
        
        try container.encode(self.parents, forKey:  .parents)
        
        var attachmentContainer = container.nestedContainer(keyedBy: CodingKeys.self, forKey: .attachments)
        
        try attachmentContainer.encode(self.iconAttachment, forKey: .icon)
        
        if (!self.content.isEmpty) {
            try encodeContent(to: encoder);
        }
    }
    
    func encodeContent(to encoder: Encoder) throws {}
    
    enum CodingKeys : String, CodingKey {
        case id = "_id"
        case isDeleted
        case name = "name"
        case createdOn = "created"
        case changedOn = "changed"
        case content
        case manufacturer = "Manufacturer"
        case generation = "Generation"
        case attachments
        case icon
        case parents
    }
}

extension FlockeEntry: Equatable {
    static func == (lhs: FlockeEntry, rhs: FlockeEntry) -> Bool {
        return lhs.id == rhs.id
    }
    
    
}
