/*
 * Copyright (C) 2012 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 <sys/socket.h>

#include <common_time/ICommonClock.h>
#include <binder/Parcel.h>

#include "utils.h"

namespace android {

/***** ICommonClock *****/

enum {
    IS_COMMON_TIME_VALID = IBinder::FIRST_CALL_TRANSACTION,
    COMMON_TIME_TO_LOCAL_TIME,
    LOCAL_TIME_TO_COMMON_TIME,
    GET_COMMON_TIME,
    GET_COMMON_FREQ,
    GET_LOCAL_TIME,
    GET_LOCAL_FREQ,
    GET_ESTIMATED_ERROR,
    GET_TIMELINE_ID,
    GET_STATE,
    GET_MASTER_ADDRESS,
    REGISTER_LISTENER,
    UNREGISTER_LISTENER,
};

const String16 ICommonClock::kServiceName("common_time.clock");
const uint64_t ICommonClock::kInvalidTimelineID = 0;
const int32_t ICommonClock::kErrorEstimateUnknown = 0x7FFFFFFF;

class BpCommonClock : public BpInterface<ICommonClock>
{
  public:
    BpCommonClock(const sp<IBinder>& impl)
        : BpInterface<ICommonClock>(impl) {}

    virtual status_t isCommonTimeValid(bool* valid, uint32_t* timelineID) {
        Parcel data, reply;
        data.writeInterfaceToken(ICommonClock::getInterfaceDescriptor());
        status_t status = remote()->transact(IS_COMMON_TIME_VALID,
                                             data,
                                             &reply);
        if (status == OK) {
            status = reply.readInt32();
            if (status == OK) {
                *valid = reply.readInt32();
                *timelineID = reply.readInt32();
            }
        }
        return status;
    }

    virtual status_t commonTimeToLocalTime(int64_t commonTime,
            int64_t* localTime) {
        Parcel data, reply;
        data.writeInterfaceToken(ICommonClock::getInterfaceDescriptor());
        data.writeInt64(commonTime);
        status_t status = remote()->transact(COMMON_TIME_TO_LOCAL_TIME,
                data, &reply);
        if (status == OK) {
            status = reply.readInt32();
            if (status == OK) {
                *localTime = reply.readInt64();
            }
        }
        return status;
    }

    virtual status_t localTimeToCommonTime(int64_t localTime,
            int64_t* commonTime) {
        Parcel data, reply;
        data.writeInterfaceToken(ICommonClock::getInterfaceDescriptor());
        data.writeInt64(localTime);
        status_t status = remote()->transact(LOCAL_TIME_TO_COMMON_TIME,
                data, &reply);
        if (status == OK) {
            status = reply.readInt32();
            if (status == OK) {
                *commonTime = reply.readInt64();
            }
        }
        return status;
    }

    virtual status_t getCommonTime(int64_t* commonTime) {
        Parcel data, reply;
        data.writeInterfaceToken(ICommonClock::getInterfaceDescriptor());
        status_t status = remote()->transact(GET_COMMON_TIME, data, &reply);
        if (status == OK) {
            status = reply.readInt32();
            if (status == OK) {
                *commonTime = reply.readInt64();
            }
        }
        return status;
    }

    virtual status_t getCommonFreq(uint64_t* freq) {
        Parcel data, reply;
        data.writeInterfaceToken(ICommonClock::getInterfaceDescriptor());
        status_t status = remote()->transact(GET_COMMON_FREQ, data, &reply);
        if (status == OK) {
            status = reply.readInt32();
            if (status == OK) {
                *freq = reply.readInt64();
            }
        }
        return status;
    }

    virtual status_t getLocalTime(int64_t* localTime) {
        Parcel data, reply;
        data.writeInterfaceToken(ICommonClock::getInterfaceDescriptor());
        status_t status = remote()->transact(GET_LOCAL_TIME, data, &reply);
        if (status == OK) {
            status = reply.readInt32();
            if (status == OK) {
                *localTime = reply.readInt64();
            }
        }
        return status;
    }

    virtual status_t getLocalFreq(uint64_t* freq) {
        Parcel data, reply;
        data.writeInterfaceToken(ICommonClock::getInterfaceDescriptor());
        status_t status = remote()->transact(GET_LOCAL_FREQ, data, &reply);
        if (status == OK) {
            status = reply.readInt32();
            if (status == OK) {
                *freq = reply.readInt64();
            }
        }
        return status;
    }

    virtual status_t getEstimatedError(int32_t* estimate) {
        Parcel data, reply;
        data.writeInterfaceToken(ICommonClock::getInterfaceDescriptor());
        status_t status = remote()->transact(GET_ESTIMATED_ERROR, data, &reply);
        if (status == OK) {
            status = reply.readInt32();
            if (status == OK) {
                *estimate = reply.readInt32();
            }
        }
        return status;
    }

    virtual status_t getTimelineID(uint64_t* id) {
        Parcel data, reply;
        data.writeInterfaceToken(ICommonClock::getInterfaceDescriptor());
        status_t status = remote()->transact(GET_TIMELINE_ID, data, &reply);
        if (status == OK) {
            status = reply.readInt32();
            if (status == OK) {
                *id = static_cast<uint64_t>(reply.readInt64());
            }
        }
        return status;
    }

    virtual status_t getState(State* state) {
        Parcel data, reply;
        data.writeInterfaceToken(ICommonClock::getInterfaceDescriptor());
        status_t status = remote()->transact(GET_STATE, data, &reply);
        if (status == OK) {
            status = reply.readInt32();
            if (status == OK) {
                *state = static_cast<State>(reply.readInt32());
            }
        }
        return status;
    }

    virtual status_t getMasterAddr(struct sockaddr_storage* addr) {
        Parcel data, reply;
        data.writeInterfaceToken(ICommonClock::getInterfaceDescriptor());
        status_t status = remote()->transact(GET_MASTER_ADDRESS, data, &reply);
        if (status == OK) {
            status = reply.readInt32();
            if (status == OK)
                deserializeSockaddr(&reply, addr);
        }
        return status;
    }

    virtual status_t registerListener(
            const sp<ICommonClockListener>& listener) {
        Parcel data, reply;
        data.writeInterfaceToken(ICommonClock::getInterfaceDescriptor());
        data.writeStrongBinder(IInterface::asBinder(listener));

        status_t status = remote()->transact(REGISTER_LISTENER, data, &reply);

        if (status == OK) {
            status = reply.readInt32();
        }

        return status;
    }

    virtual status_t unregisterListener(
            const sp<ICommonClockListener>& listener) {
        Parcel data, reply;
        data.writeInterfaceToken(ICommonClock::getInterfaceDescriptor());
        data.writeStrongBinder(IInterface::asBinder(listener));
        status_t status = remote()->transact(UNREGISTER_LISTENER, data, &reply);

        if (status == OK) {
            status = reply.readInt32();
        }

        return status;
    }
};

IMPLEMENT_META_INTERFACE(CommonClock, "android.os.ICommonClock");

status_t BnCommonClock::onTransact(uint32_t code,
                                   const Parcel& data,
                                   Parcel* reply,
                                   uint32_t flags) {
    switch(code) {
        case IS_COMMON_TIME_VALID: {
            CHECK_INTERFACE(ICommonClock, data, reply);
            bool valid;
            uint32_t timelineID;
            status_t status = isCommonTimeValid(&valid, &timelineID);
            reply->writeInt32(status);
            if (status == OK) {
                reply->writeInt32(valid);
                reply->writeInt32(timelineID);
            }
            return OK;
        } break;

        case COMMON_TIME_TO_LOCAL_TIME: {
            CHECK_INTERFACE(ICommonClock, data, reply);
            int64_t commonTime = data.readInt64();
            int64_t localTime;
            status_t status = commonTimeToLocalTime(commonTime, &localTime);
            reply->writeInt32(status);
            if (status == OK) {
                reply->writeInt64(localTime);
            }
            return OK;
        } break;

        case LOCAL_TIME_TO_COMMON_TIME: {
            CHECK_INTERFACE(ICommonClock, data, reply);
            int64_t localTime = data.readInt64();
            int64_t commonTime;
            status_t status = localTimeToCommonTime(localTime, &commonTime);
            reply->writeInt32(status);
            if (status == OK) {
                reply->writeInt64(commonTime);
            }
            return OK;
        } break;

        case GET_COMMON_TIME: {
            CHECK_INTERFACE(ICommonClock, data, reply);
            int64_t commonTime;
            status_t status = getCommonTime(&commonTime);
            reply->writeInt32(status);
            if (status == OK) {
                reply->writeInt64(commonTime);
            }
            return OK;
        } break;

        case GET_COMMON_FREQ: {
            CHECK_INTERFACE(ICommonClock, data, reply);
            uint64_t freq;
            status_t status = getCommonFreq(&freq);
            reply->writeInt32(status);
            if (status == OK) {
                reply->writeInt64(freq);
            }
            return OK;
        } break;

        case GET_LOCAL_TIME: {
            CHECK_INTERFACE(ICommonClock, data, reply);
            int64_t localTime;
            status_t status = getLocalTime(&localTime);
            reply->writeInt32(status);
            if (status == OK) {
                reply->writeInt64(localTime);
            }
            return OK;
        } break;

        case GET_LOCAL_FREQ: {
            CHECK_INTERFACE(ICommonClock, data, reply);
            uint64_t freq;
            status_t status = getLocalFreq(&freq);
            reply->writeInt32(status);
            if (status == OK) {
                reply->writeInt64(freq);
            }
            return OK;
        } break;

        case GET_ESTIMATED_ERROR: {
            CHECK_INTERFACE(ICommonClock, data, reply);
            int32_t error;
            status_t status = getEstimatedError(&error);
            reply->writeInt32(status);
            if (status == OK) {
                reply->writeInt32(error);
            }
            return OK;
        } break;

        case GET_TIMELINE_ID: {
            CHECK_INTERFACE(ICommonClock, data, reply);
            uint64_t id;
            status_t status = getTimelineID(&id);
            reply->writeInt32(status);
            if (status == OK) {
                reply->writeInt64(static_cast<int64_t>(id));
            }
            return OK;
        } break;

        case GET_STATE: {
            CHECK_INTERFACE(ICommonClock, data, reply);
            State state;
            status_t status = getState(&state);
            reply->writeInt32(status);
            if (status == OK) {
                reply->writeInt32(static_cast<int32_t>(state));
            }
            return OK;
        } break;

        case GET_MASTER_ADDRESS: {
            CHECK_INTERFACE(ICommonClock, data, reply);
            struct sockaddr_storage addr;
            status_t status = getMasterAddr(&addr);

            if ((status == OK) && !canSerializeSockaddr(&addr)) {
                status = UNKNOWN_ERROR;
            }

            reply->writeInt32(status);

            if (status == OK) {
                serializeSockaddr(reply, &addr);
            }

            return OK;
        } break;

        case REGISTER_LISTENER: {
            CHECK_INTERFACE(ICommonClock, data, reply);
            sp<ICommonClockListener> listener =
                interface_cast<ICommonClockListener>(data.readStrongBinder());
            status_t status = registerListener(listener);
            reply->writeInt32(status);
            return OK;
        } break;

        case UNREGISTER_LISTENER: {
            CHECK_INTERFACE(ICommonClock, data, reply);
            sp<ICommonClockListener> listener =
                interface_cast<ICommonClockListener>(data.readStrongBinder());
            status_t status = unregisterListener(listener);
            reply->writeInt32(status);
            return OK;
        } break;
    }
    return BBinder::onTransact(code, data, reply, flags);
}

/***** ICommonClockListener *****/

enum {
    ON_TIMELINE_CHANGED = IBinder::FIRST_CALL_TRANSACTION,
};

class BpCommonClockListener : public BpInterface<ICommonClockListener>
{
  public:
    BpCommonClockListener(const sp<IBinder>& impl)
        : BpInterface<ICommonClockListener>(impl) {}

    virtual void onTimelineChanged(uint64_t timelineID) {
        Parcel data, reply;
        data.writeInterfaceToken(
                ICommonClockListener::getInterfaceDescriptor());
        data.writeInt64(timelineID);
        remote()->transact(ON_TIMELINE_CHANGED, data, &reply);
    }
};

IMPLEMENT_META_INTERFACE(CommonClockListener,
                         "android.os.ICommonClockListener");

status_t BnCommonClockListener::onTransact(
        uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) {
    switch(code) {
        case ON_TIMELINE_CHANGED: {
            CHECK_INTERFACE(ICommonClockListener, data, reply);
            uint32_t timelineID = data.readInt64();
            onTimelineChanged(timelineID);
            return NO_ERROR;
        } break;
    }

    return BBinder::onTransact(code, data, reply, flags);
}

}; // namespace android
