#include "type.h"

#include <maps/libs/common/include/exception.h>

#include <iostream>
#include <map>

namespace maps::wiki::json2ymapsdf::ymapsdf::schema {

namespace {

const std::map<std::string, Type> NAME2TYPE = {
    {"int", Type::Integer},
    {"int2", Type::Integer},
    {"int4", Type::Integer},
    {"int8", Type::Integer},
    {"bool", Type::Bool},
    {"bpchar", Type::Text},
    {"varchar", Type::Text},
    {"text", Type::Text},
    {"geometry", Type::Geometry},
    {"bytea", Type::ByteArray},
    {"float", Type::Double},
    {"float8", Type::Double},
    {"double", Type::Double},
    {"jsonb", Type::Json},
};

const std::map<Type, std::string> TYPE2NAME = {
    {Type::Integer, "int"},
    {Type::Bool, "bool"},
    {Type::Text, "text"},
    {Type::Geometry, "geometry"},
    {Type::ByteArray, "bytea"},
    {Type::Double, "double"},
    {Type::Json, "json"},
};

} // namespace


std::istream&
operator >> (std::istream& stream, Type& type)
{
    std::string typeName;
    stream >> typeName;
    auto it = NAME2TYPE.find(typeName);
    REQUIRE(it != NAME2TYPE.end(), "Unknown type name_ '" << typeName << "'");
    type = it->second;
    return stream;
}

std::ostream&
operator << (std::ostream& stream, const Type& type)
{
    auto it = TYPE2NAME.find(type);
    REQUIRE(it != TYPE2NAME.end(), "Unknown type id '" << static_cast<int>(type)<<"'");
    stream << it->second;
    return stream;
}

} // namespace maps::wiki::json2ymapsdf::ymapsdf::schema
