const INDENT: &'static str = "    ";

fn strip_formatting(code: &str) -> String {
    let mut code = code.replace('\n', " ").replace('\r', " ").replace("\t", " ");
    loop {
        let new_code = code.replace("  ", " ").replace(" }", "}");
        if new_code.len() == code.len() {
            break;
        }
        code = new_code;
    }
    //for &c in PARENS.iter().chain(SYMBOLS) {
    //    let from0 = format!("{c} ");
    //    let from1 = format!(" {c}");
    //    let to = c;
    //    code = code.replace(&from0, to).replace(&from1, to);
    //}
    code
}

pub fn reformat(input: &str) -> String {
    let mut code = strip_formatting(input);

    code = code.replace("if(", "if (");
    code = code.replace("while(", "while (");
    code = code.replace("for(", "for (");
    code = code.replace("){", ") {");

    let mut new_code = String::new();

    let mut depth = 0;
    let mut forced_newline = false;


    for c in code.chars() {
        if forced_newline && c == ' ' {
            continue;
        }
        if forced_newline && c != '}' {
            for _ in 0..depth {
                new_code += INDENT;
            }
            forced_newline = false;
        }
        if [';', '{', '}'].contains(&c) {
            forced_newline = true;
            if c == '{' {
                new_code += "{\n";
                depth += 1;
            } else if c == '}' {
                depth -= 1;
                for _ in 0..depth {
                    new_code += INDENT;
                }
                new_code += "}\n";
            } else {
                new_code += ";\n";
            }
        } else {
            new_code.push(c);
        }
    }

    new_code.trim().to_string()
}