/*
 * Copyright (C) 2011 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 <common_time/local_clock.h>
#include <utils/String8.h>

#include "common_clock_service.h"
#include "common_clock.h"
#include "common_time_server.h"

namespace android {

sp<CommonClockService> CommonClockService::instantiate(
        CommonTimeServer& timeServer) {
    sp<CommonClockService> tcc = new CommonClockService(timeServer);
    if (tcc == NULL)
        return NULL;

    defaultServiceManager()->addService(ICommonClock::kServiceName, tcc);
    return tcc;
}

status_t CommonClockService::dump(int fd, const Vector<String16>& args) {
    Mutex::Autolock lock(mRegistrationLock);
    return mTimeServer.dumpClockInterface(fd, args, mListeners.size());
}

status_t CommonClockService::isCommonTimeValid(bool* valid,
                                               uint32_t* timelineID) {
    return mTimeServer.isCommonTimeValid(valid, timelineID);
}

status_t CommonClockService::commonTimeToLocalTime(int64_t  commonTime,
                                                   int64_t* localTime) {
    return mTimeServer.getCommonClock().commonToLocal(commonTime, localTime);
}

status_t CommonClockService::localTimeToCommonTime(int64_t  localTime,
                                                   int64_t* commonTime) {
    return mTimeServer.getCommonClock().localToCommon(localTime, commonTime);
}

status_t CommonClockService::getCommonTime(int64_t* commonTime) {
    return localTimeToCommonTime(mTimeServer.getLocalClock().getLocalTime(), commonTime);
}

status_t CommonClockService::getCommonFreq(uint64_t* freq) {
    *freq = mTimeServer.getCommonClock().getCommonFreq();
    return OK;
}

status_t CommonClockService::getLocalTime(int64_t* localTime) {
    *localTime = mTimeServer.getLocalClock().getLocalTime();
    return OK;
}

status_t CommonClockService::getLocalFreq(uint64_t* freq) {
    *freq = mTimeServer.getLocalClock().getLocalFreq();
    return OK;
}

status_t CommonClockService::getEstimatedError(int32_t* estimate) {
    *estimate = mTimeServer.getEstimatedError();
    return OK;
}

status_t CommonClockService::getTimelineID(uint64_t* id) {
    *id = mTimeServer.getTimelineID();
    return OK;
}

status_t CommonClockService::getState(State* state) {
    *state = mTimeServer.getState();
    return OK;
}

status_t CommonClockService::getMasterAddr(struct sockaddr_storage* addr) {
    return mTimeServer.getMasterAddr(addr);
}

status_t CommonClockService::registerListener(
        const sp<ICommonClockListener>& listener) {
    Mutex::Autolock lock(mRegistrationLock);

    {   // scoping for autolock pattern
        Mutex::Autolock lock(mCallbackLock);
        // check whether this is a duplicate
        for (size_t i = 0; i < mListeners.size(); i++) {
            if (IInterface::asBinder(mListeners[i]) == IInterface::asBinder(listener))
                return ALREADY_EXISTS;
        }
    }

    mListeners.add(listener);
    mTimeServer.reevaluateAutoDisableState(0 != mListeners.size());
    return IInterface::asBinder(listener)->linkToDeath(this);
}

status_t CommonClockService::unregisterListener(
        const sp<ICommonClockListener>& listener) {
    Mutex::Autolock lock(mRegistrationLock);
    status_t ret_val = NAME_NOT_FOUND;

    {   // scoping for autolock pattern
        Mutex::Autolock lock(mCallbackLock);
        for (size_t i = 0; i < mListeners.size(); i++) {
            if (IInterface::asBinder(mListeners[i]) == IInterface::asBinder(listener)) {
                IInterface::asBinder(mListeners[i])->unlinkToDeath(this);
                mListeners.removeAt(i);
                ret_val = OK;
                break;
            }
        }
    }

    mTimeServer.reevaluateAutoDisableState(0 != mListeners.size());
    return ret_val;
}

void CommonClockService::binderDied(const wp<IBinder>& who) {
    Mutex::Autolock lock(mRegistrationLock);

    {   // scoping for autolock pattern
        Mutex::Autolock lock(mCallbackLock);
        for (size_t i = 0; i < mListeners.size(); i++) {
            if (IInterface::asBinder(mListeners[i]) == who) {
                mListeners.removeAt(i);
                break;
            }
        }
    }

    mTimeServer.reevaluateAutoDisableState(0 != mListeners.size());
}

void CommonClockService::notifyOnTimelineChanged(uint64_t timelineID) {
    Mutex::Autolock lock(mCallbackLock);

    for (size_t i = 0; i < mListeners.size(); i++) {
        mListeners[i]->onTimelineChanged(timelineID);
    }
}

}; // namespace android
