use crate::get_test_file;
use anyhow::Context;
use std::io::Write;

pub fn generate_abs_path_tests() -> anyhow::Result<()> {
    let mut test_file = get_test_file("abs_path_tests.rs")?;

    for (line, path) in include_str!("../resources/tests/parsers/component/abs_path/valid.txt").lines().enumerate() {
        write!(
            test_file,
            include_str!("../resources/tests/parsers/component/abs_path/template.txt"),
            number = format!("{:03}", line),
            path = path
        )
        .context(format!("failed to write test abs_path::case_{}", line))?;
    }

    Ok(())
}

pub fn generate_authority_tests() -> anyhow::Result<()> {
    let mut test_file = get_test_file("authority_tests.rs")?;

    for (line, authority) in
        include_str!("../resources/tests/parsers/component/authority/valid.txt").lines().enumerate()
    {
        write!(
            test_file,
            include_str!("../resources/tests/parsers/component/authority/template.txt"),
            number = format!("{:03}", line),
            authority = authority
        )
        .context(format!("failed to write test authority::case_{}", line))?;
    }

    Ok(())
}

pub fn generate_domain_label_tests() -> anyhow::Result<()> {
    let mut test_file = get_test_file("domain_label_tests.rs")?;

    for (line, label) in include_str!("../resources/tests/parsers/component/domain_label/valid.txt").lines().enumerate()
    {
        write!(
            test_file,
            include_str!("../resources/tests/parsers/component/domain_label/template.txt"),
            number = format!("{:03}", line),
            label = label
        )
        .context(format!("failed to write test domain_label::case_{}", line))?;
    }

    Ok(())
}

pub fn generate_hier_part_tests() -> anyhow::Result<()> {
    let mut test_file = get_test_file("hier_part_tests.rs")?;

    for (line, part) in include_str!("../resources/tests/parsers/component/hier_part/valid.txt").lines().enumerate() {
        write!(
            test_file,
            include_str!("../resources/tests/parsers/component/hier_part/template.txt"),
            number = format!("{:03}", line),
            part = part
        )
        .context(format!("failed to write test hier_part::case_{}", line))?;
    }

    Ok(())
}

pub fn generate_host_tests() -> anyhow::Result<()> {
    let mut test_file = get_test_file("host_tests.rs")?;

    for (line, host) in include_str!("../resources/tests/parsers/component/host/valid.txt").lines().enumerate() {
        write!(
            test_file,
            include_str!("../resources/tests/parsers/component/host/template.txt"),
            number = format!("{:03}", line),
            host = host
        )
        .context(format!("failed to write test host::case_{}", line))?;
    }

    Ok(())
}

pub fn generate_hostname_tests() -> anyhow::Result<()> {
    let mut test_file = get_test_file("hostname_tests.rs")?;

    for (line, host) in include_str!("../resources/tests/parsers/component/hostname/valid.txt").lines().enumerate() {
        write!(
            test_file,
            include_str!("../resources/tests/parsers/component/hostname/template.txt"),
            number = format!("{:03}", line),
            host = host
        )
        .context(format!("failed to write test hostname::case_{}", line))?;
    }

    Ok(())
}

pub fn generate_ipv4_address_tests() -> anyhow::Result<()> {
    let mut test_file = get_test_file("ipv4_address_tests.rs")?;

    for (line, address) in
        include_str!("../resources/tests/parsers/component/ipv4_address/valid.txt").lines().enumerate()
    {
        write!(
            test_file,
            include_str!("../resources/tests/parsers/component/ipv4_address/template.txt"),
            number = format!("{:03}", line),
            address = address
        )
        .context(format!("failed to write test ipv4_address::case_{}", line))?;
    }

    Ok(())
}

pub fn generate_net_path_tests() -> anyhow::Result<()> {
    let mut test_file = get_test_file("net_path_tests.rs")?;

    for (line, path) in include_str!("../resources/tests/parsers/component/net_path/valid.txt").lines().enumerate() {
        write!(
            test_file,
            include_str!("../resources/tests/parsers/component/net_path/template.txt"),
            number = format!("{:03}", line),
            path = path
        )
        .context(format!("failed to write test net_path::case_{}", line))?;
    }

    Ok(())
}

pub fn generate_opaque_part_tests() -> anyhow::Result<()> {
    let mut test_file = get_test_file("opaque_part_tests.rs")?;

    for (line, part) in include_str!("../resources/tests/parsers/component/opaque_part/valid.txt").lines().enumerate() {
        write!(
            test_file,
            include_str!("../resources/tests/parsers/component/opaque_part/template.txt"),
            number = format!("{:03}", line),
            part = part
        )
        .context(format!("failed to write test opaque_part::case_{}", line))?;
    }

    Ok(())
}

pub fn generate_path_segments_tests() -> anyhow::Result<()> {
    let mut test_file = get_test_file("path_segments_tests.rs")?;

    for (line, segments) in
        include_str!("../resources/tests/parsers/component/path_segments/valid.txt").lines().enumerate()
    {
        write!(
            test_file,
            include_str!("../resources/tests/parsers/component/path_segments/template.txt"),
            number = format!("{:03}", line),
            segments = segments
        )
        .context(format!("failed to write test path_segments::case_{}", line))?;
    }

    Ok(())
}

pub fn generate_rel_path_tests() -> anyhow::Result<()> {
    let mut test_file = get_test_file("rel_path_tests.rs")?;

    for (line, path) in include_str!("../resources/tests/parsers/component/rel_path/valid.txt").lines().enumerate() {
        write!(
            test_file,
            include_str!("../resources/tests/parsers/component/rel_path/template.txt"),
            number = format!("{:03}", line),
            path = path
        )
        .context(format!("failed to write test rel_path::case_{}", line))?;
    }

    Ok(())
}

pub fn generate_scheme_tests() -> anyhow::Result<()> {
    let mut test_file = get_test_file("scheme_tests.rs")?;

    for (line, scheme) in include_str!("../resources/tests/parsers/component/scheme/valid.txt").lines().enumerate() {
        write!(
            test_file,
            include_str!("../resources/tests/parsers/component/scheme/template.txt"),
            number = format!("{:03}", line),
            scheme = scheme
        )
        .context(format!("failed to write test scheme::case_{}", line))?;
    }

    Ok(())
}

pub fn generate_segment_tests() -> anyhow::Result<()> {
    let mut test_file = get_test_file("segment_tests.rs")?;

    for (line, segment) in include_str!("../resources/tests/parsers/component/segment/valid.txt").lines().enumerate() {
        write!(
            test_file,
            include_str!("../resources/tests/parsers/component/segment/template.txt"),
            number = format!("{:03}", line),
            segment = segment
        )
        .context(format!("failed to write test segment::case_{}", line))?;
    }

    Ok(())
}

pub fn generate_server_tests() -> anyhow::Result<()> {
    let mut test_file = get_test_file("server_tests.rs")?;

    for (line, server) in include_str!("../resources/tests/parsers/component/server/valid.txt").lines().enumerate() {
        write!(
            test_file,
            include_str!("../resources/tests/parsers/component/server/template.txt"),
            number = format!("{:03}", line),
            server = server
        )
        .context(format!("failed to write test server::case_{}", line))?;
    }

    Ok(())
}

pub fn generate_top_label_tests() -> anyhow::Result<()> {
    let mut test_file = get_test_file("top_label_tests.rs")?;

    for (line, label) in include_str!("../resources/tests/parsers/component/top_label/valid.txt").lines().enumerate() {
        write!(
            test_file,
            include_str!("../resources/tests/parsers/component/top_label/template.txt"),
            number = format!("{:03}", line),
            label = label
        )
        .context(format!("failed to write test top_label::case_{}", line))?;
    }

    Ok(())
}
