//
//  main.swift
//  
//
//  Created by Thibaut Schmitt on 20/12/2021.
//

import ToolCore
import Foundation
import ArgumentParser

struct Colors: ParsableCommand {
    
    // MARK: - CommandConfiguration
    
    static var configuration = CommandConfiguration(
        abstract: "A utility for generate colors assets and their getters.",
        version: ResgenSwiftVersion
    )
    
    // MARK: - Static
    
    static let toolName = "Color"
    static let defaultExtensionName = "Color"
    static let defaultExtensionNameUIKit = "UIColor"
    static let assetsColorsFolderName = "Colors"
    
    // MARK: - Command options
    
    @OptionGroup var options: ColorsToolOptions
    
    // MARK: - Run
    
    public func run() throws {
        print("[\(Self.toolName)] Starting colors generation")
                
        // Check requirements
        guard checkRequirements() else { return }
        
        print("[\(Self.toolName)] Will generate colors")
        
        // Delete current colors
        deleteCurrentColors()

        // Get colors to generate
        let parsedColors = ColorFileParser.parse(options.inputFile,
                                                colorStyle: options.style)
        // -> Time: 0.0020350217819213867 seconds

        // Generate all colors in xcassets
        ColorXcassetHelper.generateXcassetColors(colors: parsedColors,
                                                 to: options.xcassetsPath)
        // -> Time: 3.4505380392074585 seconds

        // Generate extension
        ColorExtensionGenerator.writeExtensionFile(colors: parsedColors,
                                                   staticVar: options.staticMembers,
                                                   extensionName: options.extensionName,
                                                   extensionFilePath: options.extensionFilePath,
                                                   isSwiftUI: true)
        
        // Generate extension
        ColorExtensionGenerator.writeExtensionFile(colors: parsedColors,
                                                   staticVar: options.staticMembers,
                                                   extensionName: options.extensionNameUIKit,
                                                   extensionFilePath: options.extensionFilePathUIKit,
                                                   isSwiftUI: false)
        
        print("[\(Self.toolName)] Colors generated")
    }
    
    // MARK: - Requirements
    
    private func checkRequirements() -> Bool {
        let fileManager = FileManager()
        
        // Check if input file exists
        guard fileManager.fileExists(atPath: options.inputFile) else {
            let error = ColorsToolError.fileNotExists(options.inputFile)
            print(error.description)
            Colors.exit(withError: error)
        }
        
        // Check if xcassets file exists
        guard fileManager.fileExists(atPath: options.xcassetsPath) else {
            let error = ColorsToolError.fileNotExists(options.xcassetsPath)
            print(error.description)
            Colors.exit(withError: error)
        }
        
        // Extension for UIKit and SwiftUI should have different name
        guard options.extensionName != options.extensionNameUIKit else {
            let error = ColorsToolError.extensionNamesCollision(options.extensionName)
            print(error.description)
            Colors.exit(withError: error)
        }
        
        // Check if needed to regenerate
        guard GeneratorChecker.shouldGenerate(force: options.forceGeneration,
                                              inputFilePath: options.inputFile,
                                              extensionFilePath: options.extensionFilePath) else {
            print("[\(Self.toolName)] Colors are already up to date :) ")
            return false
        }
        
        return true
    }
    
    // MARK: - Helpers
    
    private func deleteCurrentColors() {
        let fileManager = FileManager()
        let assetsColorPath = "\(options.xcassetsPath)/Colors"
        
        if fileManager.fileExists(atPath: assetsColorPath) {
            do {
                try fileManager.removeItem(atPath: assetsColorPath)
            } catch {
                let error = ColorsToolError.deleteExistingColors("\(options.xcassetsPath)/Colors")
                print(error.description)
                Colors.exit(withError: error)
            }
        }
    }
}
