/**
 *
 * @file src/trace/values/Name.cpp
 *
 * @copyright 2008-2024 Bordeaux INP, CNRS (LaBRI UMR 5800), Inria,
 *                      Univ. Bordeaux. All rights reserved.
 *
 * @author Camille Ordronneau
 * @author Johnny Jazeix
 * @author Mathieu Faverge
 * @author Thibault Soucarre
 * @author Kevin Coulomb
 * @author Pascal Noisette
 * @author Olivier Lagrasse
 * @author Augustin Degomme
 *
 * @date 2024-07-17
 */
#include <string>
/* -- */
#include "trace/values/Value.hpp"
#include "trace/values/String.hpp"
#include <cstdio>
#include <ostream>
#include "trace/values/Name.hpp"

Name::Name() {
    _is_correct = false;
}

Name::Name(std::string name, std::string alias) :
    _alias(std::move(alias)), _name(std::move(name)) {
    _is_correct = true;
}

Name::Name(const std::string &name) :
    _alias(name), _name(name) {
    _is_correct = true;
}

Name::Name(const String &name) :
    _alias(name.to_string()), _name(name.to_string()) {
    _is_correct = true;
}

std::string Name::get_name() const {
    return _name;
}

std::string Name::get_alias() const {
    return _alias;
}

void Name::set_name(std::string name) {
    _name = std::move(name);
}

void Name::set_alias(std::string alias) {
    _alias = std::move(alias);
}

String Name::to_String() const {
    if (!_name.empty())
        return String(_name);
    else
        return String(_alias);
}

std::string Name::to_string() const {
    if (!_name.empty())
        return _name;
    else
        return _alias;
}

bool Name::operator==(Name &s) const {
    if (!_name.empty() && !_alias.empty() && !s.get_alias().empty() && !s.get_name().empty()) {
        return (s.get_name() == _name || s.get_name() == _alias);
    }
    else if (!_name.empty()) {
        return s.get_name() == _name;
    }
    else if (!_alias.empty()) {
        return s.get_alias() == _alias;
    }
    return false;
}

bool Name::operator==(String &s) const {
    return s == _alias || s == _name;
}

bool Name::operator==(std::string &s) const {
    return s == _alias || s == _name;
}

bool Name::operator<(std::string &s) const {
    return _name < s;
}

bool Name::operator<(const Name &s) const {
    if (!_alias.empty())
        return _alias < s.get_alias();

    if (!_alias.empty() && !s.get_alias().empty())
        return _alias < s.get_alias();
    else if (!_name.empty() && !s.get_name().empty())
        return _name < s.get_name();
    return false;
}

std::ostream &operator<<(std::ostream &os, const Name &obj) {
    os << "(" << obj.get_alias() << ", " << obj.get_name();
    return os;
}
