#include "code_text.h"

#include <cstddef>

namespace {

// Blanquea desde start hasta la comilla que cierra. Devuelve dónde sigue el texto.
std::size_t blank_literal(std::string& text, std::size_t start) {
    char quote = text[start];
    std::size_t i = start + 1;
    while (i < text.size() && text[i] != quote && text[i] != '\n') {
        i += text[i] == '\\' ? 2 : 1;
    }
    std::size_t end = i < text.size() ? i + 1 : text.size();
    for (std::size_t j = start; j < end; j++) {
        if (text[j] != '\n') {
            text[j] = ' ';
        }
    }
    return end;
}

// Blanquea un comentario de bloque que empieza en start. Devuelve dónde sigue el texto.
std::size_t blank_block_comment(std::string& text, std::size_t start) {
    std::size_t close = text.find("*/", start + 2);
    std::size_t end = close == std::string::npos ? text.size() : close + 2;
    for (std::size_t j = start; j < end; j++) {
        if (text[j] != '\n') {
            text[j] = ' ';
        }
    }
    return end;
}

}  // namespace

std::string blank_comments_and_literals(const std::string& code) {
    std::string text = code;
    std::size_t i = 0;
    while (i < text.size()) {
        if (text.compare(i, 2, "//") == 0) {
            while (i < text.size() && text[i] != '\n') {
                text[i] = ' ';
                i++;
            }
        } else if (text.compare(i, 2, "/*") == 0) {
            i = blank_block_comment(text, i);
        } else if (text[i] == '"' || text[i] == '\'') {
            i = blank_literal(text, i);
        } else {
            i++;
        }
    }
    return text;
}
