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

import CoreVideo
import Foundation
import ToolCore

enum TagsGenerator {

    static func writeExtensionFiles(
        sections: [Section],
        lang: String,
        tags: [String],
        staticVar: Bool,
        extensionName: String,
        extensionFilePath: String
    ) {
        // Get extension content
        let extensionFileContent = Self.getExtensionContent(
            sections: sections,
            lang: lang,
            tags: tags,
            staticVar: staticVar,
            extensionName: extensionName
        )

        // Write content
        let extensionFilePathURL = URL(fileURLWithPath: extensionFilePath)
        do {
            try extensionFileContent.write(to: extensionFilePathURL, atomically: false, encoding: .utf8)
        } catch {
            let error = StringiumError.writeFile(extensionFilePath, error.localizedDescription)
            print(error.description)
            Stringium.exit(withError: error)
        }
    }

    // MARK: - Extension content

    static func getExtensionContent(
        sections: [Section],
        lang: String,
        tags: [String],
        staticVar: Bool,
        extensionName: String
    ) -> String {
        [
            Self.getHeader(
                extensionClassname: extensionName,
                staticVar: staticVar
            ),
            Self.getProperties(
                sections: sections,
                lang: lang,
                tags: tags,
                staticVar: staticVar
            ),
            Self.getFooter()
        ]
            .joined(separator: "\n")
    }

    // MARK: - Extension part

    private static func getHeader(extensionClassname: String, staticVar: Bool) -> String {
        """
        // Generated by ResgenSwift.Strings.\(Tags.toolName) \(ResgenSwiftVersion)

        \(staticVar ? "typelias Tags = String\n\n" : "")import UIKit

        extension \(extensionClassname) {
        """
    }

    private static func getProperties(
        sections: [Section],
        lang: String,
        tags: [String],
        staticVar: Bool
    ) -> String {
        sections
            .compactMap { section in
                // Check that at least one string will be generated
                guard section.hasOneOrMoreMatchingTags(tags: tags) else {
                    return nil // Go to next section
                }

                var res = "\n    // MARK: - \(section.name)"
                section.definitions.forEach { definition in
                    guard definition.hasOneOrMoreMatchingTags(inputTags: tags) == true else {
                        return // Go to next definition
                    }

                    if staticVar {
                        res += "\n\n\(definition.getStaticProperty(forLang: lang))"
                    } else {
                        res += "\n\n\(definition.getProperty(forLang: lang))"
                    }
                }
                return res
            }
            .joined(separator: "\n")
    }

    private static func getFooter() -> String {
        """
        }

        """
    }
}
