using util::AbstractMain
using util::Arg
using util::Opt
using fandoc::FandocParser
using fandoc::MarkdownDocWriter
using fandoc::FandocDocWriter

** Converts Markdown ('.md') files to Fandoc ('.fandoc') files and vice-versa. 
class Main : AbstractMain {
    @Arg { help = "Source Markdown (.md) or Fandoc (.fandoc) file to convert." }
    File? srcFile
    @Arg { help = "Name of the destination file. Defaults to source filename with the opposite extension." }
    Str[]? targetFile
    @Opt { aliases=[ "o" ]; help = "Overwrite target file if exists. By default aborts the process if the target file exists." }
    Bool overwrite := false
    @Opt { aliases=[ "l" ]; help = "Sets the logging level to any of [silent, err, warn, info, debug]." }
    LogLevel logLevel :=
    override Int run() {
        log.level = logLevel"Log level: ${log.level}")
        ext := srcFile.ext
        if (ext == null)
            throw Err("Source file must have either .md (Markdown) or .fandoc (Fandoc) extension.")

        switch (ext.lower) {
            case "md"       : parseMarkdown
            case "fandoc"   : parseFandoc
            default         : throw Err("Unsupported file extension: .${ext}; only .md and .fandoc files are supported.")

        return 0
    private Str readInput() { "Reading source file `${srcFile}`" )
        content := srcFile.readAllStr
        log.debug( content )
        return content
    private OutStream openOutputStream (Str ext) {
        uri := targetFile != null 
            ? Uri(targetFile[0]) 
            : srcFile.uri.plusName(srcFile.basename + ".${ext}")
        outputFile := File(uri)
        if (outputFile.exists && !overwrite)
            throw Err("Process aborted because the target file exists `${outputFile}`. Use option -o to overwrite.")"Creating output file `${outputFile}`")
        return outputFile.out
    private Void parseMarkdown() {
        markdownDoc := MarkdownParser().parse(readInput)"Markdown file parsed")
        outStream := openOutputStream("fandoc")
        markdownDoc.write(FandocDocWriter(outStream ))
    private Void parseFandoc() {"Reading source file `${srcFile}`")
        fandocDoc := FandocParser().parse(,"Fandoc file parsed")
        outStream := openOutputStream("md")
    private Void closeOutput(OutStream outStream) {