#include <algorithm>
#include <string>
#include <vector>

#include "UhdmAstUpstream.h"
#include "frontends/ast/ast.h"

YOSYS_NAMESPACE_BEGIN

AST::AstNode *mkconst_real(double d)
{
    AST::AstNode *node = new AST::AstNode(AST::AST_REALVALUE);
    node->realvalue = d;
    return node;
}

namespace VERILOG_FRONTEND
{

using namespace AST;

// divide an arbitrary length decimal number by two and return the rest
static int my_decimal_div_by_two(std::vector<uint8_t> &digits)
{
    int carry = 0;
    for (size_t i = 0; i < digits.size(); i++) {
        if (digits[i] >= 10)
            log_file_error(current_filename, get_line_num(), "Invalid use of [a-fxz?] in decimal constant.\n");
        digits[i] += carry * 10;
        carry = digits[i] % 2;
        digits[i] /= 2;
    }
    while (!digits.empty() && !digits.front())
        digits.erase(digits.begin());
    return carry;
}

// find the number of significant bits in a binary number (not including the sign bit)
static int my_ilog2(int x)
{
    int ret = 0;
    while (x != 0 && x != -1) {
        x = x >> 1;
        ret++;
    }
    return ret;
}

// parse a binary, decimal, hexadecimal or octal number with support for special bits ('x', 'z' and '?')
static void my_strtobin(std::vector<RTLIL::State> &data, const char *str, int len_in_bits, int base, char case_type, bool is_unsized)
{
    // all digits in string (MSB at index 0)
    std::vector<uint8_t> digits;

    while (*str) {
        if ('0' <= *str && *str <= '9')
            digits.push_back(*str - '0');
        else if ('a' <= *str && *str <= 'f')
            digits.push_back(10 + *str - 'a');
        else if ('A' <= *str && *str <= 'F')
            digits.push_back(10 + *str - 'A');
        else if (*str == 'x' || *str == 'X')
            digits.push_back(0xf0);
        else if (*str == 'z' || *str == 'Z' || *str == '?')
            digits.push_back(0xf1);
        str++;
    }

    if (base == 10 && GetSize(digits) == 1 && digits.front() >= 0xf0)
        base = 2;

    data.clear();

    if (base == 10) {
        while (!digits.empty())
            data.push_back(my_decimal_div_by_two(digits) ? State::S1 : State::S0);
    } else {
        int bits_per_digit = my_ilog2(base - 1);
        for (auto it = digits.rbegin(), e = digits.rend(); it != e; it++) {
            if (*it > (base - 1) && *it < 0xf0)
                log_file_error(current_filename, get_line_num(), "Digit larger than %d used in in base-%d constant.\n", base - 1, base);
            for (int i = 0; i < bits_per_digit; i++) {
                int bitmask = 1 << i;
                if (*it == 0xf0)
                    data.push_back(case_type == 'x' ? RTLIL::Sa : RTLIL::Sx);
                else if (*it == 0xf1)
                    data.push_back(case_type == 'x' || case_type == 'z' ? RTLIL::Sa : RTLIL::Sz);
                else
                    data.push_back((*it & bitmask) ? State::S1 : State::S0);
            }
        }
    }

    int len = GetSize(data);
    RTLIL::State msb = data.empty() ? State::S0 : data.back();

    if (len_in_bits < 0) {
        if (len < 32)
            data.resize(32, msb == State::S0 || msb == State::S1 ? RTLIL::S0 : msb);
        return;
    }

    if (is_unsized && (len > len_in_bits))
        log_file_error(current_filename, get_line_num(), "Unsized constant must have width of 1 bit, but have %d bits!\n", len);

    for (len = len - 1; len >= 0; len--)
        if (data[len] == State::S1)
            break;
    if (msb == State::S0 || msb == State::S1) {
        len += 1;
        data.resize(len_in_bits, State::S0);
    } else {
        len += 2;
        data.resize(len_in_bits, msb);
    }

    if (len_in_bits == 0)
        log_file_error(current_filename, get_line_num(), "Illegal integer constant size of zero (IEEE 1800-2012, 5.7).\n");

    if (len > len_in_bits)
        log_warning("Literal has a width of %d bit, but value requires %d bit. (%s:%d)\n", len_in_bits, len, current_filename.c_str(),
                    get_line_num());
}

// convert the Verilog code for a constant to an AST node
AST::AstNode *const2ast(std::string code, char case_type, bool warn_z)
{
    if (warn_z) {
        AST::AstNode *ret = const2ast(code, case_type, false);
        if (ret != nullptr && std::find(ret->bits.begin(), ret->bits.end(), RTLIL::State::Sz) != ret->bits.end())
            log_warning("Yosys has only limited support for tri-state logic at the moment. (%s:%d)\n", current_filename.c_str(), get_line_num());
        return ret;
    }

    const char *str = code.c_str();

    // Strings
    if (*str == '"') {
        int len = strlen(str) - 2;
        std::vector<RTLIL::State> data;
        data.reserve(len * 8);
        for (int i = 0; i < len; i++) {
            unsigned char ch = str[len - i];
            for (int j = 0; j < 8; j++) {
                data.push_back((ch & 1) ? State::S1 : State::S0);
                ch = ch >> 1;
            }
        }
        AST::AstNode *ast = AST::AstNode::mkconst_bits(data, false);
        ast->str = code;
        return ast;
    }

    for (size_t i = 0; i < code.size(); i++)
        if (code[i] == '_' || code[i] == ' ' || code[i] == '\t' || code[i] == '\r' || code[i] == '\n')
            code.erase(code.begin() + (i--));
    str = code.c_str();

    char *endptr;
    long len_in_bits = strtol(str, &endptr, 10);

    // Simple base-10 integer
    if (*endptr == 0) {
        std::vector<RTLIL::State> data;
        my_strtobin(data, str, -1, 10, case_type, false);
        if (data.back() == State::S1)
            data.push_back(State::S0);
        return AST::AstNode::mkconst_bits(data, true);
    }

    // unsized constant
    if (str == endptr)
        len_in_bits = -1;

    // The "<bits>'[sS]?[bodhBODH]<digits>" syntax
    if (*endptr == '\'') {
        std::vector<RTLIL::State> data;
        bool is_signed = false;
        bool is_unsized = len_in_bits < 0;
        if (*(endptr + 1) == 's' || *(endptr + 1) == 'S') {
            is_signed = true;
            endptr++;
        }
        switch (*(endptr + 1)) {
        case 'b':
        case 'B':
            my_strtobin(data, endptr + 2, len_in_bits, 2, case_type, is_unsized);
            break;
        case 'o':
        case 'O':
            my_strtobin(data, endptr + 2, len_in_bits, 8, case_type, is_unsized);
            break;
        case 'd':
        case 'D':
            my_strtobin(data, endptr + 2, len_in_bits, 10, case_type, is_unsized);
            break;
        case 'h':
        case 'H':
            my_strtobin(data, endptr + 2, len_in_bits, 16, case_type, is_unsized);
            break;
        default:
            char next_char = char(tolower(*(endptr + 1)));
            if (next_char == '0' || next_char == '1' || next_char == 'x' || next_char == 'z') {
                is_unsized = true;
                my_strtobin(data, endptr + 1, 1, 2, case_type, is_unsized);
            } else {
                return NULL;
            }
        }
        if (len_in_bits < 0) {
            if (is_signed && data.back() == State::S1)
                data.push_back(State::S0);
        }
        return AST::AstNode::mkconst_bits(data, is_signed, is_unsized);
    }

    return NULL;
}
} // namespace VERILOG_FRONTEND

YOSYS_NAMESPACE_END
