//
//  LibraryExport.swift
//  Zockerhoehle
//
//  Created by Julian-Steffen Müller on 19.11.19.
//  Copyright © 2019 Julian-Steffen Müller. All rights reserved.
//

import Foundation
import Compression

struct LibraryExporter : Encodable {
    private var games : [Game]
    private var consoles : [Console]
    private var gameSeries : [GameSeries]
    private var accessories : [Accessory]
    
    init (games: [Game], consoles: [Console], gameSeries: [GameSeries], accessories : [Accessory]) {
        self.games = games
        self.consoles = consoles
        self.gameSeries = gameSeries
        self.accessories = accessories
    }
    
    enum CodingKeys: String, CodingKey {
        case games
        case consoles
        case gameSeries
        case accessories
    }
    
    func encode(to encoder: Encoder) throws {
        var container = encoder.container(keyedBy: CodingKeys.self)
        try container.encode(games, forKey: .games)
        try container.encode(consoles, forKey: .consoles)
        try container.encode(gameSeries, forKey: .gameSeries)
        try container.encode(accessories, forKey: .accessories)
    }
    
    func export() -> Data? {
        let jsonEncoder = JSONEncoder()
        
        do {
            let exportJSON = try jsonEncoder.encode(self)
            return exportJSON
        }catch {
            return Data?.none
        }
    }
    
    func export(name : String) {
        if let data = export() {
            //let exportFileName = "libExp_\(Date().formattedInTimeZone()).json"
            let exportFileName = "libExp_\(name).json"
            let byteCount = data.count // replace with data.count
            let bcf = ByteCountFormatter()
            bcf.allowedUnits = [.useMB] // optional: restricts the units to MB only
            bcf.countStyle = .file
            let fileSizeAsString = bcf.string(fromByteCount: Int64(byteCount))
            print("Exported Library to '\(exportFileName)' (Size: \(fileSizeAsString))")
            
            do {
                if let documentDirectory = ICloudManager.backup_folder {
                    let encodedFileURL = documentDirectory.appendingPathComponent(exportFileName)
                    print("WRITE TO \(encodedFileURL)")
                    try data.write(to: encodedFileURL)
                }
                
            }catch let error {
                print("Export failed. Error \(error)")
            }
        }
    }
    
    //Currently python decoder missing 15 characters
    func exportCompressedZLIB() -> Data? {
        if let data = self.export() {
            let exportString = String(data: data, encoding: .utf8)!
            
            var sourceBuffer = Array(exportString.utf8)
            let destinationBuffer = UnsafeMutablePointer<UInt8>.allocate(capacity: exportString.count)
            
            let algorithm = COMPRESSION_ZLIB
            
            let compressedSize = compression_encode_buffer(destinationBuffer, exportString.count,
                                                           &sourceBuffer, exportString.count,
                                                           nil,
                                                           algorithm)
            
            if compressedSize > 0 {
                let exportData = NSData(bytesNoCopy: destinationBuffer, length: compressedSize) as Data
                
                return exportData
            }else {
                print("LibraryExport::exportCompressedZLIB - Compression failed 'compressedSite == 0'")
                return Data?.none
            }
        }
        
        return Data?.none
    }
}
