// Copyright 2015 Google Inc. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

//! Command line tool to exercise pulldown-cmark.

#![forbid(unsafe_code)]

use pulldown_cmark::{html, BrokenLink, Options, Parser};

use std::env;
use std::fs::File;
use std::io::{self, Read};
use std::path::PathBuf;

fn dry_run(text: &str, opts: Options, broken_links: &mut Vec<BrokenLink<'static>>) {
    let p = Parser::new_with_broken_link_callback(
        text,
        opts,
        Some(|link: BrokenLink<'_>| {
            broken_links.push(link.into_static());
            None
        }),
    );
    let count = p.count();
    println!("{} events", count);
}

fn print_events(text: &str, opts: Options, broken_links: &mut Vec<BrokenLink<'static>>) {
    let parser = Parser::new_with_broken_link_callback(
        text,
        opts,
        Some(|link: BrokenLink<'_>| {
            broken_links.push(link.into_static());
            None
        }),
    )
    .into_offset_iter();
    for (event, range) in parser {
        println!("{:?}: {:?}", range, event);
    }
    println!("EOF");
}

fn brief(program: &str) -> String {
    format!(
        "Usage: {} [options]\n\n{}",
        program, "Reads markdown from file or standard input and emits HTML.",
    )
}

pub fn main() -> std::io::Result<()> {
    let args: Vec<_> = env::args().collect();
    let mut opts = getopts::Options::new();
    opts.optflag("h", "help", "this help message");
    opts.optflag("d", "dry-run", "dry run, produce no output");
    opts.optflag("e", "events", "print event sequence instead of rendering");
    opts.optflag("T", "enable-tables", "enable GitHub-style tables");
    opts.optflag("m", "enable-math", "enable LaTeX-style math");
    opts.optflag("F", "enable-footnotes", "enable GitHub-style footnotes");
    opts.optflag("", "enable-old-footnotes", "enable Hoedown-style footnotes");
    opts.optflag(
        "S",
        "enable-strikethrough",
        "enable GitHub-style strikethrough",
    );
    opts.optflag("L", "enable-tasklists", "enable GitHub-style task lists");
    opts.optflag("P", "enable-smart-punctuation", "enable smart punctuation");
    opts.optflag(
        "H",
        "enable-heading-attributes",
        "enable heading attributes",
    );
    opts.optflag("M", "enable-metadata-blocks", "enable metadata blocks");
    opts.optflag(
        "R",
        "reject-broken-links",
        "fail if input file has broken links",
    );

    let matches = match opts.parse(&args[1..]) {
        Ok(m) => m,
        Err(f) => {
            eprintln!("{}\n{}", f, opts.usage(&brief(&args[0])));
            std::process::exit(1);
        }
    };
    if matches.opt_present("help") {
        println!("{}", opts.usage(&brief(&args[0])));
        return Ok(());
    }
    let mut opts = Options::empty();
    if matches.opt_present("enable-tables") {
        opts.insert(Options::ENABLE_TABLES);
    }
    if matches.opt_present("enable-math") {
        opts.insert(Options::ENABLE_MATH);
    }
    if matches.opt_present("enable-footnotes") {
        opts.insert(Options::ENABLE_FOOTNOTES);
    }
    if matches.opt_present("enable-old-footnotes") {
        opts.insert(Options::ENABLE_OLD_FOOTNOTES);
    }
    if matches.opt_present("enable-strikethrough") {
        opts.insert(Options::ENABLE_STRIKETHROUGH);
    }
    if matches.opt_present("enable-tasklists") {
        opts.insert(Options::ENABLE_TASKLISTS);
    }
    if matches.opt_present("enable-smart-punctuation") {
        opts.insert(Options::ENABLE_SMART_PUNCTUATION);
    }
    if matches.opt_present("enable-heading-attributes") {
        opts.insert(Options::ENABLE_HEADING_ATTRIBUTES);
    }
    if matches.opt_present("enable-metadata-blocks") {
        opts.insert(Options::ENABLE_YAML_STYLE_METADATA_BLOCKS);
        opts.insert(Options::ENABLE_PLUSES_DELIMITED_METADATA_BLOCKS);
    }

    let mut input = String::new();
    let mut broken_links = vec![];
    if !&matches.free.is_empty() {
        for filename in &matches.free {
            let real_path = PathBuf::from(filename);
            let mut f = File::open(&real_path).expect("file not found");
            f.read_to_string(&mut input)
                .expect("something went wrong reading the file");
            if matches.opt_present("events") {
                print_events(&input, opts, &mut broken_links);
            } else if matches.opt_present("dry-run") {
                dry_run(&input, opts, &mut broken_links);
            } else {
                pulldown_cmark(&input, opts, &mut broken_links);
            }
        }
    } else {
        let _ = io::stdin().lock().read_to_string(&mut input);
        if matches.opt_present("events") {
            print_events(&input, opts, &mut broken_links);
        } else if matches.opt_present("dry-run") {
            dry_run(&input, opts, &mut broken_links);
        } else {
            pulldown_cmark(&input, opts, &mut broken_links);
        }
    }

    if matches.opt_present("reject-broken-links") && !broken_links.is_empty() {
        eprintln!("Error: {} broken links:", broken_links.len());
        for link in broken_links {
            let start = link.span.start;
            let end = link.span.end;
            let reference = link.reference;
            eprintln!("[{start}-{end}]: {reference}");
        }
        std::process::exit(1);
    }

    Ok(())
}

pub fn pulldown_cmark(input: &str, opts: Options, broken_links: &mut Vec<BrokenLink<'static>>) {
    let mut p = Parser::new_with_broken_link_callback(
        input,
        opts,
        Some(|link: BrokenLink<'_>| {
            broken_links.push(link.into_static());
            None
        }),
    );
    let stdio = io::stdout();
    let buffer = std::io::BufWriter::with_capacity(1024 * 1024, stdio.lock());
    let _ = html::write_html_io(buffer, &mut p);
}
