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

#ifndef ANDROID_RS_BUILD_FOR_HOST
#include "rsContext.h"
#else
#include "rsContextHostStub.h"
#endif

using namespace android;
using namespace android::renderscript;

ObjectBase::ObjectBase(Context *rsc)
{
    mUserRefCount = 0;
    mSysRefCount = 0;
    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.size()) {
        LOGV("%s RSobj %p, name %s, refs %i,%i  from %s,%i links %p,%p,%p",
             op, this, mName.string(), 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)
{
    mName.setTo(name);
}

void ObjectBase::setName(const char *name, uint32_t len)
{
    mName.setTo(name, len);
}

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.");
        dumpAll(rsc);
    }
}

void ObjectBase::dumpAll(Context *rsc)
{
    LOGV("Dumping all objects");
    const ObjectBase * o = rsc->mObjHead;
    while (o) {
        LOGV(" Object %p", o);
        o->dumpLOGV("  ");
        o = o->mNext;
    }
}

