mod errorsd;
mod informationd;
mod warningsd;
use self::errorsd::*;
use self::informationd::*;
use self::warningsd::*;

macro_rules! error_occurred {
    () => {
        $crate::ERROR_OCCURRED.store(true, Ordering::Relaxed);
    };
}

macro_rules! warning_occurred {
    () => {
        $crate::WARNING_OCCURRED.store(true, Ordering::Relaxed);
    };
}

macro_rules! e0001 {
    ($fmt1:expr, $fmt2:expr, $fmt3:expr) => {{
        error_occurred!();
        error!(
            "{}   Bad character {} ({:#02x}) found in file name {} at offset {}",
            "E0001", $fmt1, $fmt1 as usize, $fmt2, $fmt3
        );
    }};
}

macro_rules! e0002 {
    ($fmt1:expr, $fmt2:expr) => {{
        error_occurred!();
        error!(
            "{}   File {} has bad permissions: {}",
            "E0002", $fmt1, $fmt2
        );
    }};
}

macro_rules! e0003 {
    ($fmt:expr) => {{
        error_occurred!();
        error!("{}   {} is no text file", "E0003", $fmt);
    }};
}

macro_rules! e0004 {
    ($fmt:expr) => {{
        error_occurred!();
        error!("{}   Empty directory {} detected", "E0004", $fmt);
    }};
}

macro_rules! e0005 {
    ($fmt:expr) => {{
        error_occurred!();
        error!("{}   Empty file {} detected", "E0005", $fmt);
    }};
}

macro_rules! e0006 {
    ($fmt:expr) => {{
        error_occurred!();
        error!("{}   Hidden directory {} detected", "E0006", $fmt);
    }};
}

macro_rules! e0006t {
    ($fmt:expr) => {{
        error_occurred!();
        error!(
            "{}   Hidden directory {} detected in TDS zip archive",
            "E0006", $fmt
        );
    }};
}

macro_rules! e0007 {
    ($fmt:expr) => {{
        error_occurred!();
        error!("{}   Hidden file {} detected", "E0007", $fmt);
    }};
}

macro_rules! e0007t {
    ($fmt:expr) => {{
        error_occurred!();
        error!(
            "{}   Hidden file {} detected in TDS zip archive",
            "E0007", $fmt
        );
    }};
}

macro_rules! e0008 {
    ($fmt:expr) => {{
        error_occurred!();
        error!("{}   Temporary file {} detected", "E0008", $fmt);
    }};
}

macro_rules! e0008t {
    ($fmt:expr) => {{
        error_occurred!();
        error!(
            "{}   Temporary file {} detected in TDS zip archive",
            "E0008", $fmt
        );
    }};
}
macro_rules! e0009 {
    () => {{
        error_occurred!();
        error!(
            "{}   One of README/README.md/README.txt must exist",
            "E0009",
        );
    }};
}

macro_rules! e0010 {
    ($fmt:expr) => {{
        error_occurred!();
        error!("{}   {} is a broken symlink", "E0010", $fmt);
    }};
}

macro_rules! e0011 {
    ($fmt1:expr, $fmt2:expr) => {{
        error_occurred!();
        error!(
            "{}   Directory {} has bad permissions: {}",
            "E0011", $fmt1, $fmt2
        );
    }};
}

macro_rules! e0012 {
    ($fmt:expr) => {{
        error_occurred!();
        error!("{}   File {} has CRLF line endings", "E0012", $fmt);
    }};
}

macro_rules! e0013 {
    ($fmt:expr) => {{
        error_occurred!();
        error!("{}   {} is a socket special file", "E0013", $fmt);
    }};
}

macro_rules! e0014 {
    ($fmt:expr) => {{
        error_occurred!();
        error!("{}   {} is a fifo file", "E0014", $fmt);
    }};
}

macro_rules! e0015 {
    ($fmt:expr) => {{
        error_occurred!();
        error!("{}   {} is a block device file", "E0015", $fmt);
    }};
}

macro_rules! e0016 {
    ($fmt:expr) => {{
        error_occurred!();
        error!("{}   {} is a character device file", "E0016", $fmt);
    }};
}

macro_rules! e0017 {
    ($fmt:expr) => {{
        error_occurred!();
        error!("{}   PDF error detected in {}", "E0017", $fmt);
    }};
}

macro_rules! e0018 {
    ($fmt:expr) => {{
        error_occurred!();
        error!("{}   Unwanted directory {} detected", "E0018", $fmt);
    }};
}

macro_rules! e0019 {
    ($fmt1:expr, $fmt2:expr) => {{
        error_occurred!();
        error!("{}   {} generated by {} exists", "E0019", $fmt1, $fmt2);
    }};
}

macro_rules! e0020 {
    ($fmt:expr) => {{
        error_occurred!();
        error!(
            "{}   Unwanted directory `{}` detected in the top level directory of a TDS archive",
            "E0020", $fmt
        );
    }};
}

macro_rules! e0021 {
    ($fmt1:expr, $fmt2:expr, $fmt3:expr) => {{
        error_occurred!();
        error!(
            "{}   File {} : Error reading in line {}: {}",
            "E0021", $fmt1, $fmt2, $fmt3
        );
    }};
}

macro_rules! e0022 {
    ($fmt1:expr, $fmt2:expr) => {{
        error_occurred!();
        error!("{}   {}: `{}`", "E0022", $fmt1, $fmt2);
    }};
}
macro_rules! e0023 {
    ($fmt:expr) => {{
        error_occurred!();
        error!("{}   {}", "E0023", $fmt);
    }};
}

macro_rules! e0024 {
    ($fmt1:expr, $fmt2:expr) => {{
        error_occurred!();
        error!(
            "{}   The TDS zip archive {} has bad permissions: {}",
            "E0024", $fmt1, $fmt2
        );
    }};
}

macro_rules! e0025 {
    ($fmt:expr) => {{
        error_occurred!();
        error!(
            "{}   Duplicate names when ignoring letter case for: {}",
            "E0025", $fmt
        );
    }};
}

macro_rules! e0026 {
    ($fmt:expr) => {{
        error_occurred!();
        error!(
            "{}   {} : file not in TDS or different in TDS and non-install tree",
            "E0026", $fmt
        );
    }};
}

macro_rules! e0027 {
    ($fmt1:expr, $fmt2:expr) => {{
        error_occurred!();
        error!(
            "{}   {}: An I/O error occurred -> {}",
            "E0027", $fmt1, $fmt2
        );
    }};
}

macro_rules! e0028 {
    ($fmt1:expr, $fmt2:expr) => {{
        error_occurred!();
        error!(
            "{}   No directory {} (= package name) found in path {}",
            "E0028", $fmt1, $fmt2
        );
    }};
}

macro_rules! e0029 {
    ($fmt1:expr, $fmt2:expr) => {{
        error_occurred!();
        error!(
            "{}   {}: {} encoding with BOM detected",
            "E0029", $fmt1, $fmt2
        );
    }};
}

macro_rules! e0030 {
    ($fmt1:expr, $fmt2:expr) => {{
        error_occurred!();
        error!(
            "{}   Symlink {} points to {} which is outside of the package directory tree",
            "E0030", $fmt1, $fmt2
        );
    }};
}

macro_rules! e0031 {
    ($fmt:expr) => {{
        error_occurred!();
        error!(
            "{}   File name {} contains invalid UTF-8 character(s)",
            "E0031", $fmt
        );
    }};
}

macro_rules! e0032 {
    ($fmt1:expr, $fmt2:expr, $fmt3:expr) => {{
        error_occurred!();
        error!(
            "{}   File {} : expected {}, got {}",
            "E0032", $fmt1, $fmt2, $fmt3
        );
    }};
}

macro_rules! e0034 {
    ($fmt:expr) => {{
        error_occurred!();
        error!(
            "{}   Unwanted file `{}` detected in the top level directory of a TDS archive",
            "E0034", $fmt
        );
    }};
}

macro_rules! e0035 {
    ($fmt:expr) => {{
        error_occurred!();
        error!(
            "{}   Unwanted TDS archive `{}` detected in package directory tree",
            "E0035", $fmt
        );
    }};
}

macro_rules! e0036 {
    ($fmt:expr) => {{
        error_occurred!();
        error!(
            "{}   File `{}` not below `source/` or `doc/` top level directory in TDS zip archive",
            "E0036", $fmt
        );
    }};
}

macro_rules! e0037 {
    ($fmt:expr) => {{
        error_occurred!();
        error!("{}   File {} has CR line endings", "E0037", $fmt);
    }};
}

macro_rules! e0038 {
    ($fmt1:expr, $fmt2:expr, $fmt3:expr, $fmt4:expr) => {{
        error_occurred!();
        error!(
            "{}   File {} has inconsistent line endings: CR={}, LF={}, CRLF={}",
            "E0038", $fmt1, $fmt2, $fmt3, $fmt4
        );
    }};
}

macro_rules! e0039 {
    () => {{
        error_occurred!();
        error!("{}   No doc/ directory found", "E0039");
    }};
}

macro_rules! e0040 {
    () => {{
        error_occurred!();
        error!(
            "{}   Too few top level directories in the TDS zip archive",
            "E0040",
        );
    }};
}

macro_rules! e0041 {
    () => {{
        error_occurred!();
        error!("{}   One or more map file found for the package but none of them is in a path starting with fonts/map/dvips", "E0041");
    }};
}

macro_rules! e0042 {
    ($fmt:expr) => {{
        error_occurred!();
        error!(
            "{}   TDS zip archive: duplicate names when ignoring letter case for: {}",
            "E0042", $fmt
        );
    }};
}

macro_rules! e0043 {
    ($fmt:expr) => {{
        error_occurred!();
        error!("{}   Symlink {} found in TDS zip archive", "E0043", $fmt);
    }};
}

macro_rules! w0001 {
    ($fmt:expr) => {{
        warning_occurred!();
        warn!("{}   Archive as package file detected: {}", "W0001", $fmt);
    }};
}

macro_rules! w0002 {
    () => {{
        warning_occurred!();
        warn!("{}   Duplicate files detected", "W0002",);
    }};
}

macro_rules! w0003 {
    ($fmt:expr) => {{
        warning_occurred!();
        warn!(
            "{}   Same named files detected in the package directory tree: {}",
            "W0003", $fmt
        );
    }};
}

macro_rules! w0004 {
    ($fmt1:expr, $fmt2:expr) => {{
        warning_occurred!();
        warn!(
            "{}   {}: {} encoding with BOM detected",
            "W0004", $fmt1, $fmt2
        );
    }};
}

macro_rules! w0005 {
    ($fmt1:expr, $fmt2:expr) => {{
        warning_occurred!();
        warn!(
            "{}   Very large file {} with size {}MiB detected",
            "W0005", $fmt1, $fmt2
        )
    }};
}

macro_rules! w0006 {
    ($fmt1:expr, $fmt2:expr) => {{
        warning_occurred!();
        warn!(
            "{}   Very large file {} with size {}MiB detected in TDS zip archive",
            "W0006", $fmt1, $fmt2
        )
    }};
}

macro_rules! w0007 {
    ($fmt:expr) => {{
        warning_occurred!();
        warn!(
            "{}   Empty directory {} detected in TDS zip archive",
            "W0007", $fmt
        );
    }};
}

macro_rules! w0008 {
    ($fmt:expr) => {{
        warning_occurred!();
        warn!("{}   Windows file {} has Unix line endings", "W0008", $fmt);
    }};
}

macro_rules! w0009 {
    ($fmt1:expr, $fmt2:expr) => {{
        warning_occurred!();
        warn!(
            "{}   Replacing `{} -> {}` with the same from config file",
            "W0009", $fmt1, $fmt2
        )
    }};
}

macro_rules! w0010 {
    ($fmt:expr) => {{
        warning_occurred!();
        warn!("{}   Hardlinks detected with inode={}", "W0010", $fmt,);
    }};
}

macro_rules! w0011 {
    ($fmt1:expr, $fmt2:expr, $fmt3:expr) => {{
        warning_occurred!();
        warn!(
            "{}   {} has an mtime in the future by {} seconds, or {}",
            "W0011", $fmt1, $fmt2, $fmt3
        )
    }};
}

macro_rules! i0002 {
    ($fmt:expr) => {{
        info!(
            "{}   {} {}",
            "I0002", "Checking package files in directory", $fmt
        );
    }};
}

macro_rules! i0003 {
    ($fmt:expr) => {{
        info!("{}   {} {}", "I0003", "Checking TDS zip archive", $fmt);
    }};
}

macro_rules! i0004 {
    ($fmt:expr) => {{
        info!("{}   Correcting line endings for file {}", "I0004", $fmt);
    }};
}

macro_rules! i0005 {
    ($fmt:expr) => {{
        info!("{}   Correcting permissions for {}", "I0005", $fmt);
    }};
}

macro_rules! i0006 {
    () => {{
        info!(
            "{}   Files having one of the following file name endings are regarded as temporary",
            "I0006",
        );
    }};
}

macro_rules! i0007 {
    ($fmt1:expr, $fmt2:expr) => {{
        info!(
            "{}   {}: Successfully corrected wrong line endings to {}",
            "I0007", $fmt1, $fmt2
        );
    }};
}

macro_rules! i0008 {
    ($fmt1:expr) => {{
        info!("{}   Using config file {}", "I0008", $fmt1);
    }};
}

macro_rules! i0009 {
    ($fmt1:expr, $fmt2:expr, $fmt3:expr) => {{
        warn!(
            "{}   Updating entry `{} -> {}` with `{} -> {}` from config file",
            "I0009", $fmt1, $fmt2, $fmt1, $fmt3
        )
    }};
}

pub fn explains(err: &str) {
    let err_upp = err.to_ascii_uppercase();
    match err_upp.as_str() {
        "E0001" => e0001d(),
        "E0002" => e0002d(),
        "E0003" => e0003d(),
        "E0004" => e0004d(),
        "E0005" => e0005d(),
        "E0006" => e0006d(),
        "E0007" => e0007d(),
        "E0008" => e0008d(),
        "E0009" => e0009d(),
        "E0010" => e0010d(),
        "E0011" => e0011d(),
        "E0012" => e0012d(),
        "E0013" => e0013d(),
        "E0014" => e0014d(),
        "E0015" => e0015d(),
        "E0016" => e0016d(),
        "E0017" => e0017d(),
        "E0018" => e0018d(),
        "E0019" => e0019d(),
        "E0020" => e0020d(),
        "E0021" => e0021d(),
        "E0022" => e0022d(),
        "E0023" => e0023d(),
        "E0024" => e0024d(),
        "E0025" => e0025d(),
        "E0026" => e0026d(),
        "E0027" => e0027d(),
        "E0028" => e0028d(),
        "E0029" => e0029d(),
        "E0030" => e0030d(),
        "E0031" => e0031d(),
        "E0032" => e0032d(),
        "E0034" => e0034d(),
        "E0035" => e0035d(),
        "E0036" => e0036d(),
        "E0037" => e0037d(),
        "E0038" => e0038d(),
        "E0039" => e0039d(),
        "E0040" => e0040d(),
        "E0041" => e0041d(),
        "E0042" => e0042d(),
        "E0043" => e0043d(),

        //        "I0001" => i0001d!(),
        "I0001" => i0001d(),
        "I0002" => i0002d(),
        "I0003" => i0003d(),
        "I0004" => i0004d(),
        "I0005" => i0005d(),
        "I0006" => i0006d(),
        "I0007" => i0007d(),
        "I0008" => i0008d(),
        "I0009" => i0009d(),

        "W0001" => w0001d(),
        "W0002" => w0002d(),
        "W0003" => w0003d(),
        "W0004" => w0004d(),
        "W0005" => w0005d(),
        "W0006" => w0006d(),
        "W0007" => w0007d(),
        "W0008" => w0008d(),
        "W0009" => w0009d(),
        "W0010" => w0010d(),
        "W0011" => w0011d(),

        e => eprintln!(
            "Unknown error code `{}` specified with option -e resp. --explain. Exiting...",
            e
        ),
    }
}

pub fn explains_all() {
    explains("E0001");
    explains("E0002");
    explains("E0003");
    explains("E0004");
    explains("E0005");
    explains("E0006");
    explains("E0007");
    explains("E0008");
    explains("E0009");
    explains("E0010");
    explains("E0011");
    explains("E0012");
    explains("E0013");
    explains("E0014");
    explains("E0015");
    explains("E0016");
    explains("E0017");
    explains("E0018");
    explains("E0019");
    explains("E0020");
    explains("E0021");
    explains("E0022");
    explains("E0023");
    explains("E0024");
    explains("E0025");
    explains("E0026");
    explains("E0027");
    explains("E0028");
    explains("E0029");
    explains("E0030");
    explains("E0031");
    explains("E0032");
    explains("E0034");
    explains("E0035");
    explains("E0036");
    explains("E0037");
    explains("E0038");
    explains("E0039");
    explains("E0040");
    explains("E0041");
    explains("E0042");
    explains("E0043");

    explains("I0001");
    explains("I0002");
    explains("I0003");
    explains("I0004");
    explains("I0005");
    explains("I0006");
    explains("I0007");
    explains("I0008");
    explains("I0009");

    explains("W0001");
    explains("W0002");
    explains("W0003");
    explains("W0004");
    explains("W0005");
    explains("W0006");
    explains("W0007");
    explains("W0008");
    explains("W0009");
    explains("W0010");
    explains("W0011");
}
