/*
 * 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.
 */

#include <binder/Status.h>

namespace android {
namespace binder {

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

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

Status Status::fromExceptionCode(int32_t exceptionCode,
                                 const String8& message) {
    return Status(exceptionCode, OK, message);
}

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

Status Status::fromServiceSpecificError(int32_t serviceSpecificErrorCode) {
    return Status(EX_SERVICE_SPECIFIC, serviceSpecificErrorCode);
}

Status Status::fromServiceSpecificError(int32_t serviceSpecificErrorCode,
                                        const String8& message) {
    return Status(EX_SERVICE_SPECIFIC, serviceSpecificErrorCode, message);
}

Status Status::fromServiceSpecificError(int32_t serviceSpecificErrorCode,
                                        const char* message) {
    return fromServiceSpecificError(serviceSpecificErrorCode, String8(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 String8& message)
    : mException(exceptionCode),
      mErrorCode(errorCode),
      mMessage(message) {}

status_t Status::readFromParcel(const Parcel& parcel) {
    status_t status = parcel.readInt32(&mException);
    if (status != OK) {
        setFromStatusT(status);
        return status;
    }

    // Skip over fat response headers.  Not used (or propagated) in native code.
    if (mException == EX_HAS_REPLY_HEADER) {
        // Note that the header size includes the 4 byte size field.
        const int32_t header_start = parcel.dataPosition();
        int32_t header_size;
        status = parcel.readInt32(&header_size);
        if (status != OK) {
            setFromStatusT(status);
            return status;
        }
        parcel.setDataPosition(header_start + header_size);
        // And fat response headers are currently only used when there are no
        // exceptions, so act like there was no error.
        mException = EX_NONE;
    }

    if (mException == EX_NONE) {
        return status;
    }

    // The remote threw an exception.  Get the message back.
    String16 message;
    status = parcel.readString16(&message);
    if (status != OK) {
        setFromStatusT(status);
        return status;
    }
    mMessage = String8(message);

    if (mException == EX_SERVICE_SPECIFIC) {
        status = parcel.readInt32(&mErrorCode);
    } else if (mException == EX_PARCELABLE) {
        // Skip over the blob of Parcelable data
        const int32_t header_start = parcel.dataPosition();
        int32_t header_size;
        status = parcel.readInt32(&header_size);
        if (status != OK) {
            setFromStatusT(status);
            return status;
        }
        parcel.setDataPosition(header_start + header_size);
    }
    if (status != OK) {
        setFromStatusT(status);
        return status;
    }

    return status;
}

status_t Status::writeToParcel(Parcel* parcel) const {
    // Something really bad has happened, and we're not going to even
    // try returning rich error data.
    if (mException == EX_TRANSACTION_FAILED) {
        return mErrorCode;
    }

    status_t status = parcel->writeInt32(mException);
    if (status != OK) { return status; }
    if (mException == EX_NONE) {
        // We have no more information to write.
        return status;
    }
    status = parcel->writeString16(String16(mMessage));
    if (mException == EX_SERVICE_SPECIFIC) {
        status = parcel->writeInt32(mErrorCode);
    } else if (mException == EX_PARCELABLE) {
        // Sending Parcelable blobs currently not supported
        status = parcel->writeInt32(0);
    }
    return status;
}

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

void Status::setServiceSpecificError(int32_t errorCode, const String8& message) {
    setException(EX_SERVICE_SPECIFIC, message);
    mErrorCode = errorCode;
}

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

String8 Status::toString8() const {
    String8 ret;
    if (mException == EX_NONE) {
        ret.append("No error");
    } else {
        ret.appendFormat("Status(%d): '", mException);
        if (mException == EX_SERVICE_SPECIFIC ||
            mException == EX_TRANSACTION_FAILED) {
            ret.appendFormat("%d: ", mErrorCode);
        }
        ret.append(String8(mMessage));
        ret.append("'");
    }
    return ret;
}

std::stringstream& operator<< (std::stringstream& stream, const Status& s) {
    stream << s.toString8().string();
    return stream;
}

}  // namespace binder
}  // namespace android
