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

import ToolCore
import Foundation
import ArgumentParser

struct Twine: ParsableCommand {
    
    // MARK: - Command Configuration
    
    static var configuration = CommandConfiguration(
        abstract: "Generate strings with twine.",
        version: ResgenSwiftVersion
    )
    
    // MARK: - Static
    
    static let toolName = "Twine"
    static let defaultExtensionName = "String"
    static let twineExecutable = "\(FileManager.default.homeDirectoryForCurrentUser.relativePath)/scripts/twine/twine"
    
    // MARK: - Command Options
    
    @OptionGroup var options: TwineOptions
    
    // MARK: - Run
    
    mutating func run() {
        print("[\(Self.toolName)] Starting strings generation")
        
        // Check requirements
        guard checkRequirements() else { return }
        
        print("[\(Self.toolName)] Will generate strings")
        
        // Generate strings files (lproj files)
        for lang in options.langs {
            Shell.shell([Self.twineExecutable,
                        "generate-localization-file", options.inputFile,
                        "--lang", "\(lang)",
                        "\(options.outputPath)/\(lang).lproj/\(options.inputFilenameWithoutExt).strings",
                        "--tags=ios,iosonly,iosOnly"])
        }
        
        // Generate extension
        Shell.shell([Self.twineExecutable,
                    "generate-localization-file", options.inputFile,
                    "--format", "apple-swift",
                    "--lang", "\(options.defaultLang)",
                    options.extensionFilePath,
                    "--tags=ios,iosonly,iosOnly"])
        
        print("[\(Self.toolName)] Strings generated")
    }
    
    // MARK: - Requirements
    
    private func checkRequirements() -> Bool {
        let fileManager = FileManager()
        
        // Input file
        guard fileManager.fileExists(atPath: options.inputFile) else {
            let error = TwineError.fileNotExists(options.inputFile)
            print(error.description)
            Twine.exit(withError: error)
        }
        
        // Langs
        guard options.langs.isEmpty == false else {
            let error = TwineError.langsListEmpty
            print(error.description)
            Twine.exit(withError: error)
        }
        
        guard options.langs.contains(options.defaultLang) else {
            let error = TwineError.defaultLangsNotInLangs
            print(error.description)
            Twine.exit(withError: error)
        }
        
        // Check if needed to regenerate
        guard GeneratorChecker.shouldGenerate(force: options.forceGeneration,
                                              inputFilePath: options.inputFile,
                                              extensionFilePath: options.extensionFilePathGenerated) else {
            print("[\(Self.toolName)] Strings are already up to date :) ")
            return false
        }
        
        return true
    }
}
