#include "sled/utility/status.h"

namespace sled {

Status::Status(Code code, const Slice &msg, const Slice &msg2)
{
    assert(code != kOk);
    state_.code    = code;
    state_.message = msg.ToString();
    if (!msg2.empty()) { state_.message += ":" + msg2.ToString(); }
}

std::string
Status::ToString() const
{
    char tmp[30];
    const char *type;
    switch (code()) {
    case kOk:
        type = "OK";
        break;
    case kInvalidArgument:
        type = "InvalidArgument: ";
        break;
    case kOutOfRange:
        type = "OutOfRange: ";
        break;
    case kUnathenticated:
        type = "Unathenticated: ";
        break;
    case kPermissionDenied:
        type = "PermissionDenied: ";
        break;
    case kNotFound:
        type = "NotFound: ";
        break;
    case kAborted:
        type = "Aborted: ";
        break;
    case kAlreadyExists:
        type = "AlreadyExists: ";
        break;
    case kResourceExhausted:
        type = "ResourceExhausted: ";
        break;
    case kCancelled:
        type = "Cancelled: ";
        break;
    case kDataLoss:
        type = "DataLoss: ";
        break;
    case kUnknown:
        type = "Unknown: ";
        break;
    case kInternal:
        type = "Internal: ";
        break;
    case kNotImplemented:
        type = "NotImplemented: ";
        break;
    case kUnavailable:
        type = "Unavailable: ";
        break;
    case kDeadlineExceeded:
        type = "DeadlineExceeded: ";
        break;
    default:
        std::snprintf(tmp, sizeof(tmp), "Unknown code(%d): ", static_cast<int>(code()));
        type = tmp;
        break;
    }

    return type + state_.message;
}

}// namespace sled
