//
//  File.swift
//  
//
//  Created by Cirno MainasuK on 2020-7-7.
//

import Foundation

class Parser {
    
    let json: [String: Any]
    
    init(data: Data) throws {
        let dict = try JSONSerialization.jsonObject(with: data, options: []) as? [String: Any]
        self.json = dict ?? [:]
    }
    
    
}

extension Parser {
    enum KeyStyle {
        case infoPlist
        case swiftgen
    }
}

extension Parser {
    
    func generateStrings(keyStyle: KeyStyle = .swiftgen) -> String {
        let pairs = traval(dictionary: json, prefixKeys: [])
        
        var lines: [String] = []
        for pair in pairs {
            let key = [
                "\"",
                pair.prefix
                    .map { segment in
                        segment
                            .split(separator: "_")
                            .map { String($0) }
                            .map {
                                switch keyStyle {
                                case .infoPlist:        return $0
                                case .swiftgen:         return $0.capitalized
                                }
                            }
                            .joined()
                    }
                    .joined(separator: "."),
                "\""
            ].joined()
            let value = [
                "\"",
                pair.value.replacingOccurrences(of: "%s", with: "%@").replacingOccurrences(of: "\"", with: "\\\""),
                "\""
            ].joined()
            let line = [
                [key, value].joined(separator: " = "),
                ";"
            ].joined()
            
            lines.append(line)
        }
        
        let strings = lines
            .sorted()
            .joined(separator: "\n")
        return strings
    }
    
}

extension Parser {
    
    typealias PrefixKeys = [String]
    typealias LocalizationPair = (prefix: PrefixKeys, value: String)

    private func traval(dictionary: [String: Any], prefixKeys: PrefixKeys) -> [LocalizationPair] {
        var pairs: [LocalizationPair] = []
        for (key, any) in dictionary {
            let prefix = prefixKeys + [key]

            // if leaf node of dict tree
            if let value = any as? String {
                pairs.append(LocalizationPair(prefix: prefix, value: value))
                continue
            }
            
            // if not leaf node of dict tree
            if let dict = any as? [String: Any] {
                let innerPairs = traval(dictionary: dict, prefixKeys: prefix)
                pairs.append(contentsOf: innerPairs)
            }
        }
        return pairs
    }
    
}
