/*
 * Copyright (C) 2009 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 "rsObjectBase.h"
#include "rsContext.h"

using namespace android;
using namespace android::renderscript;

ObjectBase::ObjectBase(Context *rsc)
{
    mUserRefCount = 0;
    mSysRefCount = 0;
    mName = NULL;
    mRSC = NULL;
    mNext = NULL;
    mPrev = NULL;
    mAllocFile = __FILE__;
    mAllocLine = __LINE__;
    setContext(rsc);
}

ObjectBase::~ObjectBase()
{
    //LOGV("~ObjectBase %p  ref %i,%i", this, mUserRefCount, mSysRefCount);
    rsAssert(!mUserRefCount);
    rsAssert(!mSysRefCount);
    remove();
}

void ObjectBase::dumpLOGV(const char *op) const
{
    if (mName) {
        LOGV("%s RSobj %p, name %s, refs %i,%i  from %s,%i links %p,%p,%p",
             op, this, mName, mUserRefCount, mSysRefCount, mAllocFile, mAllocLine, mNext, mPrev, mRSC);
    } else {
        LOGV("%s RSobj %p, no-name, refs %i,%i  from %s,%i links %p,%p,%p",
             op, this, mUserRefCount, mSysRefCount, mAllocFile, mAllocLine, mNext, mPrev, mRSC);
    }
}

void ObjectBase::setContext(Context *rsc)
{
    if (mRSC) {
        remove();
    }
    mRSC = rsc;
    if (rsc) {
        add();
    }
}

void ObjectBase::incUserRef() const
{
    mUserRefCount ++;
    //LOGV("ObjectBase %p inc ref %i", this, mRefCount);
}

void ObjectBase::incSysRef() const
{
    mSysRefCount ++;
    //LOGV("ObjectBase %p inc ref %i", this, mRefCount);
}

bool ObjectBase::checkDelete() const
{
    if (!(mSysRefCount | mUserRefCount)) {
        if (mRSC && mRSC->props.mLogObjects) {
            dumpLOGV("checkDelete");
        }
        delete this;
        return true;
    }
    return false;
}

bool ObjectBase::decUserRef() const
{
    rsAssert(mUserRefCount > 0);
    mUserRefCount --;
    //dumpObj("decUserRef");
    return checkDelete();
}

bool ObjectBase::zeroUserRef() const
{
    mUserRefCount = 0;
    //dumpObj("zeroUserRef");
    return checkDelete();
}

bool ObjectBase::decSysRef() const
{
    rsAssert(mSysRefCount > 0);
    mSysRefCount --;
    //dumpObj("decSysRef");
    return checkDelete();
}

void ObjectBase::setName(const char *name)
{
    delete mName;
    mName = NULL;
    if (name) {
        mName = new char[strlen(name) +1];
        strcpy(mName, name);
    }
}

void ObjectBase::setName(const char *name, uint32_t len)
{
    delete mName;
    mName = NULL;
    if (name) {
        mName = new char[len + 1];
        memcpy(mName, name, len);
        mName[len] = 0;
    }
}

void ObjectBase::add() const
{
    rsAssert(!mNext);
    rsAssert(!mPrev);
    //LOGV("calling add  rsc %p", mRSC);
    mNext = mRSC->mObjHead;
    if (mRSC->mObjHead) {
        mRSC->mObjHead->mPrev = this;
    }
    mRSC->mObjHead = this;
}

void ObjectBase::remove() const
{
    //LOGV("calling remove  rsc %p", mRSC);
    if (!mRSC) {
        rsAssert(!mPrev);
        rsAssert(!mNext);
        return;
    }
    if (mRSC->mObjHead == this) {
        mRSC->mObjHead = mNext;
    }
    if (mPrev) {
        mPrev->mNext = mNext;
    }
    if (mNext) {
        mNext->mPrev = mPrev;
    }
    mPrev = NULL;
    mNext = NULL;
}

void ObjectBase::zeroAllUserRef(Context *rsc)
{
    if (rsc->props.mLogObjects) {
        LOGV("Forcing release of all outstanding user refs.");
    }

    // This operation can be slow, only to be called during context cleanup.
    const ObjectBase * o = rsc->mObjHead;
    while (o) {
        //LOGE("o %p", o);
        if (o->zeroUserRef()) {
            // deleted the object and possibly others, restart from head.
            o = rsc->mObjHead;
            //LOGE("o head %p", o);
        } else {
            o = o->mNext;
            //LOGE("o next %p", o);
        }
    }

    if (rsc->props.mLogObjects) {
        LOGV("Objects remaining.");
        o = rsc->mObjHead;
        while (o) {
            o->dumpLOGV("  ");
            o = o->mNext;
        }
    }
}

