use std::{env, path::Path};

use swc_common::{comments::SingleThreadedComments, Mark};
use swc_ecma_codegen::to_code_with_comments;
use swc_ecma_parser::{parse_file_as_program, Syntax, TsSyntax};
use swc_ecma_transforms_base::{fixer::paren_remover, resolver};
use swc_typescript::fast_dts::{FastDts, FastDtsOptions};

pub fn main() {
    let mut dts_code = String::new();
    let res = testing::run_test2(false, |cm, handler| {
        let name = env::args().nth(1).unwrap_or_else(|| "index.ts".to_string());
        let input = Path::new(&name);
        let fm = cm.load_file(input).expect("failed to load test case");
        let unresolved_mark = Mark::new();
        let top_level_mark = Mark::new();

        let comments = SingleThreadedComments::default();
        let mut program = parse_file_as_program(
            &fm,
            Syntax::Typescript(TsSyntax {
                tsx: true,
                ..Default::default()
            }),
            Default::default(),
            Some(&comments),
            &mut Vec::new(),
        )
        .map_err(|err| err.into_diagnostic(&handler).emit())
        .map(|program| program.apply(resolver(unresolved_mark, top_level_mark, true)))
        .map(|program| program.apply(paren_remover(None)))
        .unwrap();

        let internal_annotations = FastDts::get_internal_annotations(&comments);
        let mut checker = FastDts::new(
            fm.name.clone(),
            unresolved_mark,
            FastDtsOptions {
                internal_annotations: Some(internal_annotations),
            },
        );
        let issues = checker.transform(&mut program);
        dts_code = to_code_with_comments(Some(&comments), &program);

        for issue in issues {
            handler
                .struct_span_err(issue.range.span, &issue.message)
                .emit();
        }

        if handler.has_errors() {
            Err(())
        } else {
            Ok(())
        }
    });

    let mut output =
        format!("```==================== .D.TS ====================\n\n{dts_code}\n\n");

    if let Err(issues) = res {
        output.push_str(&format!(
            "==================== Errors ====================\n{issues}\n\n```"
        ));
    }
    println!("{output}");
}
