/*
 * 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 "rsContext.h"
#include <time.h>

using namespace android;
using namespace android::renderscript;

ScriptGroup::ScriptGroup(Context *rsc) : ObjectBase(rsc) {
}

ScriptGroup::~ScriptGroup() {
    if (mRSC->mHal.funcs.scriptgroup.destroy) {
        mRSC->mHal.funcs.scriptgroup.destroy(mRSC, this);
    }

    for (size_t ct=0; ct < mLinks.size(); ct++) {
        delete mLinks[ct];
    }
}

ScriptGroup::IO::IO(const ScriptKernelID *kid) {
    mKernel = kid;
}

ScriptGroup::Node::Node(Script *s) {
    mScript = s;
    mSeen = false;
    mOrder = 0;
}

ScriptGroup::Node * ScriptGroup::findNode(Script *s) const {
    //ALOGE("find %p   %i", s, (int)mNodes.size());
    for (size_t ct=0; ct < mNodes.size(); ct++) {
        Node *n = mNodes[ct];
        for (size_t ct2=0; ct2 < n->mKernels.size(); ct2++) {
            if (n->mKernels[ct2]->mScript == s) {
                return n;
            }
        }
    }
    return NULL;
}

bool ScriptGroup::calcOrderRecurse(Node *n, int depth) {
    n->mSeen = true;
    if (n->mOrder < depth) {
        n->mOrder = depth;
    }
    bool ret = true;
    for (size_t ct=0; ct < n->mOutputs.size(); ct++) {
        const Link *l = n->mOutputs[ct];
        Node *nt = NULL;
        if (l->mDstField.get()) {
            nt = findNode(l->mDstField->mScript);
        } else {
            nt = findNode(l->mDstKernel->mScript);
        }
        if (nt->mSeen) {
            return false;
        }
        ret &= calcOrderRecurse(nt, n->mOrder + 1);
    }
    return ret;
}

#ifndef RS_SERVER
static int CompareNodeForSort(ScriptGroup::Node *const* lhs,
                              ScriptGroup::Node *const* rhs) {
    if (lhs[0]->mOrder > rhs[0]->mOrder) {
        return 1;
    }
    return 0;
}
#else
class NodeCompare {
public:
    bool operator() (const ScriptGroup::Node* lhs,
                     const ScriptGroup::Node* rhs) {
        if (lhs->mOrder > rhs->mOrder) {
            return true;
        }
        return false;
    }
};
#endif

bool ScriptGroup::calcOrder() {
    // Make nodes
    for (size_t ct=0; ct < mKernels.size(); ct++) {
        const ScriptKernelID *k = mKernels[ct].get();
        //ALOGE(" kernel %i, %p  s=%p", (int)ct, k, mKernels[ct]->mScript);
        Node *n = findNode(k->mScript);
        //ALOGE("    n = %p", n);
        if (n == NULL) {
            n = new Node(k->mScript);
            mNodes.add(n);
        }
        n->mKernels.add(k);
    }

    // add links
    //ALOGE("link count %i", (int)mLinks.size());
    for (size_t ct=0; ct < mLinks.size(); ct++) {
        Link *l = mLinks[ct];
        //ALOGE("link  %i %p", (int)ct, l);
        Node *n = findNode(l->mSource->mScript);
        //ALOGE("link n %p", n);
        n->mOutputs.add(l);

        if (l->mDstKernel.get()) {
            //ALOGE("l->mDstKernel.get() %p", l->mDstKernel.get());
            n = findNode(l->mDstKernel->mScript);
            //ALOGE("  n1 %p", n);
            n->mInputs.add(l);
        } else {
            n = findNode(l->mDstField->mScript);
            //ALOGE("  n2 %p", n);
            n->mInputs.add(l);
        }
    }

    //ALOGE("node count %i", (int)mNodes.size());
    // Order nodes
    bool ret = true;
    for (size_t ct=0; ct < mNodes.size(); ct++) {
        Node *n = mNodes[ct];
        if (n->mInputs.size() == 0) {
            for (size_t ct2=0; ct2 < mNodes.size(); ct2++) {
                mNodes[ct2]->mSeen = false;
            }
            ret &= calcOrderRecurse(n, 0);
        }
    }

    for (size_t ct=0; ct < mKernels.size(); ct++) {
        const ScriptKernelID *k = mKernels[ct].get();
        const Node *n = findNode(k->mScript);

        if (k->mHasKernelOutput) {
            bool found = false;
            for (size_t ct2=0; ct2 < n->mOutputs.size(); ct2++) {
                if (n->mOutputs[ct2]->mSource.get() == k) {
                    found = true;
                    break;
                }
            }
            if (!found) {
                //ALOGE("add io out %p", k);
                mOutputs.add(new IO(k));
            }
        }

        if (k->mHasKernelInput) {
            bool found = false;
            for (size_t ct2=0; ct2 < n->mInputs.size(); ct2++) {
                if (n->mInputs[ct2]->mDstKernel.get() == k) {
                    found = true;
                    break;
                }
            }
            if (!found) {
                //ALOGE("add io in %p", k);
                mInputs.add(new IO(k));
            }
        }
    }

    // sort
#ifndef RS_SERVER
    mNodes.sort(&CompareNodeForSort);
#else
    std::sort(mNodes.begin(), mNodes.end(), NodeCompare());
#endif

    return ret;
}

ScriptGroup * ScriptGroup::create(Context *rsc,
                           ScriptKernelID ** kernels, size_t kernelsSize,
                           ScriptKernelID ** src, size_t srcSize,
                           ScriptKernelID ** dstK, size_t dstKSize,
                           ScriptFieldID  ** dstF, size_t dstFSize,
                           const Type ** type, size_t typeSize) {

    size_t kernelCount = kernelsSize / sizeof(ScriptKernelID *);
    size_t linkCount = typeSize / sizeof(Type *);

    //ALOGE("ScriptGroup::create kernels=%i  links=%i", (int)kernelCount, (int)linkCount);


    // Start by counting unique kernel sources

    ScriptGroup *sg = new ScriptGroup(rsc);

    sg->mKernels.reserve(kernelCount);
    for (size_t ct=0; ct < kernelCount; ct++) {
        sg->mKernels.add(kernels[ct]);
    }

    sg->mLinks.reserve(linkCount);
    for (size_t ct=0; ct < linkCount; ct++) {
        Link *l = new Link();
        l->mType = type[ct];
        l->mSource = src[ct];
        l->mDstField = dstF[ct];
        l->mDstKernel = dstK[ct];
        sg->mLinks.add(l);
    }

    sg->calcOrder();

    // allocate links
    for (size_t ct=0; ct < sg->mNodes.size(); ct++) {
        const Node *n = sg->mNodes[ct];
        for (size_t ct2=0; ct2 < n->mOutputs.size(); ct2++) {
            Link *l = n->mOutputs[ct2];
            if (l->mAlloc.get()) {
                continue;
            }
            const ScriptKernelID *k = l->mSource.get();

            Allocation * alloc = Allocation::createAllocation(rsc,
                    l->mType.get(), RS_ALLOCATION_USAGE_SCRIPT);
            l->mAlloc = alloc;

            for (size_t ct3=ct2+1; ct3 < n->mOutputs.size(); ct3++) {
                if (n->mOutputs[ct3]->mSource.get() == l->mSource.get()) {
                    n->mOutputs[ct3]->mAlloc = alloc;
                }
            }
        }
    }

    if (rsc->mHal.funcs.scriptgroup.init) {
        rsc->mHal.funcs.scriptgroup.init(rsc, sg);
    }
    return sg;
}

void ScriptGroup::setInput(Context *rsc, ScriptKernelID *kid, Allocation *a) {
    for (size_t ct=0; ct < mInputs.size(); ct++) {
        if (mInputs[ct]->mKernel == kid) {
            mInputs[ct]->mAlloc = a;

            if (rsc->mHal.funcs.scriptgroup.setInput) {
                rsc->mHal.funcs.scriptgroup.setInput(rsc, this, kid, a);
            }
            return;
        }
    }
    rsAssert(!"ScriptGroup:setInput kid not found");
}

void ScriptGroup::setOutput(Context *rsc, ScriptKernelID *kid, Allocation *a) {
    for (size_t ct=0; ct < mOutputs.size(); ct++) {
        if (mOutputs[ct]->mKernel == kid) {
            mOutputs[ct]->mAlloc = a;

            if (rsc->mHal.funcs.scriptgroup.setOutput) {
                rsc->mHal.funcs.scriptgroup.setOutput(rsc, this, kid, a);
            }
            return;
        }
    }
    rsAssert(!"ScriptGroup:setOutput kid not found");
}

void ScriptGroup::execute(Context *rsc) {
    //ALOGE("ScriptGroup::execute");
    if (rsc->mHal.funcs.scriptgroup.execute) {
        rsc->mHal.funcs.scriptgroup.execute(rsc, this);
        return;
    }

    for (size_t ct=0; ct < mNodes.size(); ct++) {
        Node *n = mNodes[ct];
        //ALOGE("node %i, order %i, in %i out %i", (int)ct, n->mOrder, (int)n->mInputs.size(), (int)n->mOutputs.size());

        for (size_t ct2=0; ct2 < n->mKernels.size(); ct2++) {
            const ScriptKernelID *k = n->mKernels[ct2];
            Allocation *ain = NULL;
            Allocation *aout = NULL;

            for (size_t ct3=0; ct3 < n->mInputs.size(); ct3++) {
                if (n->mInputs[ct3]->mDstKernel.get() == k) {
                    ain = n->mInputs[ct3]->mAlloc.get();
                    //ALOGE(" link in %p", ain);
                }
            }
            for (size_t ct3=0; ct3 < mInputs.size(); ct3++) {
                if (mInputs[ct3]->mKernel == k) {
                    ain = mInputs[ct3]->mAlloc.get();
                    //ALOGE(" io in %p", ain);
                }
            }

            for (size_t ct3=0; ct3 < n->mOutputs.size(); ct3++) {
                if (n->mOutputs[ct3]->mSource.get() == k) {
                    aout = n->mOutputs[ct3]->mAlloc.get();
                    //ALOGE(" link out %p", aout);
                }
            }
            for (size_t ct3=0; ct3 < mOutputs.size(); ct3++) {
                if (mOutputs[ct3]->mKernel == k) {
                    aout = mOutputs[ct3]->mAlloc.get();
                    //ALOGE(" io out %p", aout);
                }
            }

            n->mScript->runForEach(rsc, k->mSlot, ain, aout, NULL, 0);
        }

    }

}

void ScriptGroup::serialize(Context *rsc, OStream *stream) const {
}

RsA3DClassID ScriptGroup::getClassId() const {
    return RS_A3D_CLASS_ID_SCRIPT_GROUP;
}

ScriptGroup::Link::Link() {
}

ScriptGroup::Link::~Link() {
}

namespace android {
namespace renderscript {


RsScriptGroup rsi_ScriptGroupCreate(Context *rsc,
                           RsScriptKernelID * kernels, size_t kernelsSize,
                           RsScriptKernelID * src, size_t srcSize,
                           RsScriptKernelID * dstK, size_t dstKSize,
                           RsScriptFieldID * dstF, size_t dstFSize,
                           const RsType * type, size_t typeSize) {


    return ScriptGroup::create(rsc,
                               (ScriptKernelID **) kernels, kernelsSize,
                               (ScriptKernelID **) src, srcSize,
                               (ScriptKernelID **) dstK, dstKSize,
                               (ScriptFieldID  **) dstF, dstFSize,
                               (const Type **) type, typeSize);
}


void rsi_ScriptGroupSetInput(Context *rsc, RsScriptGroup sg, RsScriptKernelID kid,
        RsAllocation alloc) {
    //ALOGE("rsi_ScriptGroupSetInput");
    ScriptGroup *s = (ScriptGroup *)sg;
    s->setInput(rsc, (ScriptKernelID *)kid, (Allocation *)alloc);
}

void rsi_ScriptGroupSetOutput(Context *rsc, RsScriptGroup sg, RsScriptKernelID kid,
        RsAllocation alloc) {
    //ALOGE("rsi_ScriptGroupSetOutput");
    ScriptGroup *s = (ScriptGroup *)sg;
    s->setOutput(rsc, (ScriptKernelID *)kid, (Allocation *)alloc);
}

void rsi_ScriptGroupExecute(Context *rsc, RsScriptGroup sg) {
    //ALOGE("rsi_ScriptGroupExecute");
    ScriptGroup *s = (ScriptGroup *)sg;
    s->execute(rsc);
}

}
}

