
struct ImageCommand: CommandProcessor {

    static let commandType: CommandType = .image

    let content: Content

    let results: PageGenerationResults

    let language: ContentLanguage

    init(content: Content, results: PageGenerationResults, language: ContentLanguage) {
        self.content = content
        self.results = results
        self.language = language
    }

    private var thumbnailWidth: Int {
        content.settings.pages.contentWidth
    }

    private var largeImageWidth: Int {
        content.settings.pages.largeImageWidth
    }

    /**
     Format: `![image](<imageId>;<caption?>]`
     */
    func process(_ arguments: [String], markdown: Substring) -> String {
        guard (1...2).contains(arguments.count) else {
            invalid(markdown)
            return ""
        }
        let imageId = arguments[0]

        guard let image = content.image(imageId) else {
            results.missing(file: imageId, source: "Image command")
            return ""
        }
        results.used(file: image)

        if image.type == .svg || image.type == .gif {
            return simple(image: image)
        }

        let thumbnail = image.imageSet(width: thumbnailWidth, height: thumbnailWidth, language: language)
        results.require(imageSet: thumbnail)

        let largeImage = image.imageSet(width: largeImageWidth, height: largeImageWidth, language: language)
        results.require(imageSet: largeImage)

        let caption = arguments.count == 2 ? arguments[1] : nil
        return PageImage(
            imageId: imageId.replacingOccurrences(of: ".", with: "-"),
            thumbnail: thumbnail,
            largeImage: largeImage,
            caption: caption).content
    }

    private func simple(image: FileResource) -> String {
        results.require(file: image)
        let path = image.absoluteUrl
        let altText = image.localized(in: language)
        return SimpleImage(imagePath: path, altText: altText).content
    }
}
