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

#define __STDC_LIMIT_MACROS

#define LOG_TAG "common_time"
#include <utils/Log.h>

#include <inttypes.h>
#include <stdint.h>

#include <utils/Errors.h>

#include "common_clock.h"

namespace android {

CommonClock::CommonClock() {
    cur_slew_        = 0;
    cur_trans_valid_ = false;

    cur_trans_.a_zero = 0;
    cur_trans_.b_zero = 0;
    cur_trans_.a_to_b_numer = local_to_common_freq_numer_ = 1;
    cur_trans_.a_to_b_denom = local_to_common_freq_denom_ = 1;
    duration_trans_ = cur_trans_;
}

bool CommonClock::init(uint64_t local_freq) {
    Mutex::Autolock lock(&lock_);

    if (!local_freq)
        return false;

    uint64_t numer = kCommonFreq;
    uint64_t denom = local_freq;

    LinearTransform::reduce(&numer, &denom);
    if ((numer > UINT32_MAX) || (denom > UINT32_MAX)) {
        ALOGE("Overflow in CommonClock::init while trying to reduce %" PRIu64 "/%" PRIu64,
             kCommonFreq, local_freq);
        return false;
    }

    cur_trans_.a_to_b_numer = local_to_common_freq_numer_ =
        static_cast<uint32_t>(numer);
    cur_trans_.a_to_b_denom = local_to_common_freq_denom_ =
        static_cast<uint32_t>(denom);
    duration_trans_ = cur_trans_;

    return true;
}

status_t CommonClock::localToCommon(int64_t local, int64_t *common_out) const {
    Mutex::Autolock lock(&lock_);

    if (!cur_trans_valid_)
        return INVALID_OPERATION;

    if (!cur_trans_.doForwardTransform(local, common_out))
        return INVALID_OPERATION;

    return OK;
}

status_t CommonClock::commonToLocal(int64_t common, int64_t *local_out) const {
    Mutex::Autolock lock(&lock_);

    if (!cur_trans_valid_)
        return INVALID_OPERATION;

    if (!cur_trans_.doReverseTransform(common, local_out))
        return INVALID_OPERATION;

    return OK;
}

int64_t CommonClock::localDurationToCommonDuration(int64_t localDur) const {
    int64_t ret;
    duration_trans_.doForwardTransform(localDur, &ret);
    return ret;
}

void CommonClock::setBasis(int64_t local, int64_t common) {
    Mutex::Autolock lock(&lock_);

    cur_trans_.a_zero = local;
    cur_trans_.b_zero = common;
    cur_trans_valid_ = true;
}

void CommonClock::resetBasis() {
    Mutex::Autolock lock(&lock_);

    cur_trans_.a_zero = 0;
    cur_trans_.b_zero = 0;
    cur_trans_valid_ = false;
}

status_t CommonClock::setSlew(int64_t change_time, int32_t ppm) {
    Mutex::Autolock lock(&lock_);

    int64_t new_local_basis;
    int64_t new_common_basis;

    if (cur_trans_valid_) {
        new_local_basis = change_time;
        if (!cur_trans_.doForwardTransform(change_time, &new_common_basis)) {
            ALOGE("Overflow when attempting to set slew rate to %d", ppm);
            return INVALID_OPERATION;
        }
    } else {
        new_local_basis = 0;
        new_common_basis = 0;
    }

    cur_slew_ = ppm;
    uint32_t n1 = local_to_common_freq_numer_;
    uint32_t n2 = 1000000 + cur_slew_;

    uint32_t d1 = local_to_common_freq_denom_;
    uint32_t d2 = 1000000;

    // n1/d1 has already been reduced, no need to do so here.
    LinearTransform::reduce(&n1, &d2);
    LinearTransform::reduce(&n2, &d1);
    LinearTransform::reduce(&n2, &d2);

    cur_trans_.a_zero = new_local_basis;
    cur_trans_.b_zero = new_common_basis;
    cur_trans_.a_to_b_numer = n1 * n2;
    cur_trans_.a_to_b_denom = d1 * d2;

    return OK;
}

}  // namespace android
