/*
 * Copyright (C) 2015 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#define LOG_TAG "HidlStatus"
#include <android-base/logging.h>

#include <hidl/Status.h>

#include <unordered_map>

namespace android {
namespace hardware {

static std::string statusToString(status_t s) {
    const std::unordered_map<status_t, std::string> statusStrings{{
        #define STATUS_TO_STRING_PAIR(STATUS) {STATUS, #STATUS}
        STATUS_TO_STRING_PAIR(OK),
        STATUS_TO_STRING_PAIR(UNKNOWN_ERROR),
        STATUS_TO_STRING_PAIR(NO_MEMORY),
        STATUS_TO_STRING_PAIR(INVALID_OPERATION),
        STATUS_TO_STRING_PAIR(BAD_VALUE),
        STATUS_TO_STRING_PAIR(BAD_TYPE),
        STATUS_TO_STRING_PAIR(NAME_NOT_FOUND),
        STATUS_TO_STRING_PAIR(PERMISSION_DENIED),
        STATUS_TO_STRING_PAIR(NO_INIT),
        STATUS_TO_STRING_PAIR(ALREADY_EXISTS),
        STATUS_TO_STRING_PAIR(DEAD_OBJECT),
        STATUS_TO_STRING_PAIR(FAILED_TRANSACTION),
        STATUS_TO_STRING_PAIR(BAD_INDEX),
        STATUS_TO_STRING_PAIR(NOT_ENOUGH_DATA),
        STATUS_TO_STRING_PAIR(WOULD_BLOCK),
        STATUS_TO_STRING_PAIR(TIMED_OUT),
        STATUS_TO_STRING_PAIR(UNKNOWN_TRANSACTION),
        STATUS_TO_STRING_PAIR(FDS_NOT_ALLOWED),
        STATUS_TO_STRING_PAIR(UNEXPECTED_NULL)
    }};
    auto it = statusStrings.find(s);
    if (it != statusStrings.end()) {
        return it->second;
    }
    std::string str = std::to_string(s);
    char *err = strerror(-s);
    if (err != NULL) {
        str.append(1, ' ').append(err);
    }
    return str;
}

static std::string exceptionToString(int32_t ex) {
    const std::unordered_map<int32_t, std::string> exceptionStrings{{
        #define EXCEPTION_TO_STRING_PAIR(EXCEPTION) {Status::Exception::EXCEPTION, #EXCEPTION}
        EXCEPTION_TO_STRING_PAIR(EX_NONE),
        EXCEPTION_TO_STRING_PAIR(EX_SECURITY),
        EXCEPTION_TO_STRING_PAIR(EX_BAD_PARCELABLE),
        EXCEPTION_TO_STRING_PAIR(EX_ILLEGAL_ARGUMENT),
        EXCEPTION_TO_STRING_PAIR(EX_NULL_POINTER),
        EXCEPTION_TO_STRING_PAIR(EX_ILLEGAL_STATE),
        EXCEPTION_TO_STRING_PAIR(EX_NETWORK_MAIN_THREAD),
        EXCEPTION_TO_STRING_PAIR(EX_UNSUPPORTED_OPERATION),
        EXCEPTION_TO_STRING_PAIR(EX_HAS_REPLY_HEADER),
        EXCEPTION_TO_STRING_PAIR(EX_TRANSACTION_FAILED)
    }};
    auto it = exceptionStrings.find(ex);
    return it == exceptionStrings.end() ? std::to_string(ex) : it->second;
}

Status Status::ok() {
    return Status();
}

Status Status::fromExceptionCode(int32_t exceptionCode) {
    return Status(exceptionCode, OK);
}

Status Status::fromExceptionCode(int32_t exceptionCode,
                                 const char *message) {
    return Status(exceptionCode, OK, message);
}

Status Status::fromStatusT(status_t status) {
    Status ret;
    ret.setFromStatusT(status);
    return ret;
}

Status::Status(int32_t exceptionCode, int32_t errorCode)
    : mException(exceptionCode),
      mErrorCode(errorCode) {}

Status::Status(int32_t exceptionCode, int32_t errorCode, const char *message)
    : mException(exceptionCode),
      mErrorCode(errorCode),
      mMessage(message) {}

void Status::setException(int32_t ex, const char *message) {
    mException = ex;
    mErrorCode = NO_ERROR;  // an exception, not a transaction failure.
    mMessage = message;
}

void Status::setFromStatusT(status_t status) {
    mException = (status == NO_ERROR) ? EX_NONE : EX_TRANSACTION_FAILED;
    mErrorCode = status;
    mMessage.clear();
}

std::string Status::description() const {
    std::ostringstream oss;
    oss << (*this);
    return oss.str();
}

std::ostream& operator<< (std::ostream& stream, const Status& s) {
    if (s.exceptionCode() == Status::EX_NONE) {
        stream << "No error";
    } else {
        stream << "Status(" << exceptionToString(s.exceptionCode()) << "): '";
        if (s.exceptionCode() == Status::EX_TRANSACTION_FAILED) {
            stream << statusToString(s.transactionError()) << ": ";
        }
        stream << s.exceptionMessage() << "'";
    }
    return stream;
}

namespace details {
    void return_status::assertOk() const {
        if (!isOk()) {
            LOG(FATAL) << "Attempted to retrieve value from failed HIDL call: " << description();
        }
    }

    return_status::~return_status() {
        // mCheckedStatus must be checked before isOk since isOk modifies mCheckedStatus
        if (!mCheckedStatus && !isOk()) {
            LOG(FATAL) << "Failed HIDL return status not checked: " << description();
        }
    }

    return_status &return_status::operator=(return_status &&other) {
        if (!mCheckedStatus && !isOk()) {
            LOG(FATAL) << "Failed HIDL return status not checked: " << description();
        }
        std::swap(mStatus, other.mStatus);
        std::swap(mCheckedStatus, other.mCheckedStatus);
        return *this;
    }

}  // namespace details

}  // namespace hardware
}  // namespace android
