//
//  TwineFileParser.swift
//  
//
//  Created by Thibaut Schmitt on 10/01/2022.
//

import Foundation

class TwineFileParser {
    static func parse(_ inputFile: String) -> [Section] {
        let inputFileContent = try! String(contentsOfFile: inputFile, encoding: .utf8)
        let stringsByLines = inputFileContent.components(separatedBy: .newlines)
        
        var sections = [Section]()
        
        // Parse file
        stringsByLines.forEach {
            // Section
            if let section = Section.match($0) {
                sections.append(section)
                return
            }
            
            // Definition
            if let definition = Definition.match($0) {
                sections.last?.definitions.append(definition)
                return
            }
            
            // Definition content
            if $0.isEmpty == false {
                // fr = Test => ["fr ", " Test"]
                let splitLine = $0
                    .removeLeadingTrailingWhitespace()
                    .split(separator: "=")
                
                guard let lastDefinition = sections.last?.definitions.last,
                      let leftElement = splitLine.first else {
                          return
                      }
                
                let rightElement: String = splitLine.dropFirst().joined(separator: "=")
                    
                // "fr " => "fr"
                let leftHand = String(leftElement).removeTrailingWhitespace()
                // " Test" => "Test"
                let rightHand = String(rightElement).removeLeadingWhitespace()
                
                // Handle comments, tags and translation
                switch leftHand {
                case "comments":
                    lastDefinition.comment = rightHand
                    
                case "tags":
                    lastDefinition.tags = rightHand
                        .split(separator: ",")
                        .map { String($0) }
                    
                case "ref":
                    lastDefinition.reference = rightHand
                    
                default:
                    lastDefinition.translations[leftHand] = rightHand.escapeDoubleQuote()
                    // Is a plurals strings (fr:one = Test)
                    // Will be handle later
                    //if leftHand.split(separator: ":").count > 1 {
                    //    lastDefinition.isPlurals = true
                    //}
                }
            }
        }
        
        // Keep only valid definition
        var invalidDefinitionNames = [String]()
        sections.forEach { section in
            section.definitions = section.definitions
                .filter {
                    if $0.isValid == false {
                        invalidDefinitionNames.append($0.name)
                        return false
                    }
                    return true
                }
        }
        if invalidDefinitionNames.count > 0 {
            print("warning: [\(Stringium.toolName)] Found \(invalidDefinitionNames.count) definition (\(invalidDefinitionNames.joined(separator: ", "))")
        }
        
        return sections
    }
}
