
struct VideoCommand: CommandProcessor {

    static let commandType: CommandType = .video

    let content: Content

    let results: PageGenerationResults

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

    /**
     Format: `![video](<fileId>;<option1...>]`
     */
    func process(_ arguments: [String], markdown: Substring) -> String {
        guard arguments.count >= 1 else {
            invalid(markdown)
            return ""
        }
        let fileId = arguments[0].trimmed

        let options = arguments.dropFirst().compactMap { convertVideoOption($0, markdown: markdown) }

        guard let file = content.file(fileId) else {
            results.missing(file: fileId, source: "Video command")
            return ""
        }
        results.require(file: file)

        guard let videoType = file.videoType() else {
            invalid("File \(file.identifier) has an unknown video type")
            return ""
        }

        return ContentPageVideo(
            filePath: file.absoluteUrl,
            videoType: videoType,
            options: options)
        .content
    }

    private func convertVideoOption(_ videoOption: String, markdown: Substring) -> Option? {
        guard let optionText = videoOption.trimmed.nonEmpty else {
            return nil
        }
        guard let option = Option(rawValue: optionText) else {
            invalid(markdown)
            return nil
        }
        switch option {
        case .poster(let imageId):
            if let image = content.image(imageId) {
                let width = 2 * content.settings.pages.contentWidth
                let version = image.imageVersion(width: width, height: width, type: .jpg)
                results.require(image: version)
                return .poster(image: version.outputPath)
            } else {
                results.missing(file: imageId, source: "Video command poster")
                return nil // Image file not present, so skip the option
            }
        case .src(let videoId):
            if let video = content.video(videoId) {
                results.used(file: video)
                let link = video.absoluteUrl
                return .src(link)
            } else {
                results.missing(file: videoId, source: "Video command source")
                return nil // Video file not present, so skip the option
            }
        default:
            return option
        }
    }

}
