/*
 * 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(listener->asBinder());

        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(listener->asBinder());
        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
