#include "generate_java.h"
#include "AST.h"
#include "Type.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// =================================================
class VariableFactory
{
public:
    VariableFactory(const string& base); // base must be short
    Variable* Get(Type* type);
    Variable* Get(int index);
private:
    vector<Variable*> m_vars;
    string m_base;
    int m_index;
};

VariableFactory::VariableFactory(const string& base)
    :m_base(base),
     m_index(0)
{
}

Variable*
VariableFactory::Get(Type* type)
{
    char name[100];
    sprintf(name, "%s%d", m_base.c_str(), m_index);
    m_index++;
    Variable* v = new Variable(type, name);
    m_vars.push_back(v);
    return v;
}

Variable*
VariableFactory::Get(int index)
{
    return m_vars[index];
}

// =================================================
class StubClass : public Class
{
public:
    StubClass(Type* type, Type* interfaceType);
    virtual ~StubClass();

    Variable* transact_code;
    Variable* transact_data;
    Variable* transact_reply;
    Variable* transact_flags;
    SwitchStatement* transact_switch;
private:
    void make_as_interface(Type* interfaceType);
};

StubClass::StubClass(Type* type, Type* interfaceType)
    :Class()
{
    this->comment = "/** Local-side IPC implementation stub class. */";
    this->modifiers = PUBLIC | ABSTRACT | STATIC;
    this->what = Class::CLASS;
    this->type = type;
    this->extends = BINDER_NATIVE_TYPE;
    this->interfaces.push_back(interfaceType);

    // descriptor
    Field* descriptor = new Field(STATIC | FINAL | PRIVATE,
                            new Variable(STRING_TYPE, "DESCRIPTOR"));
    descriptor->value = "\"" + interfaceType->QualifiedName() + "\"";
    this->elements.push_back(descriptor);

    // ctor
    Method* ctor = new Method;
        ctor->modifiers = PUBLIC;
        ctor->comment = "/** Construct the stub at attach it to the "
                        "interface. */";
        ctor->name = "Stub";
        ctor->statements = new StatementBlock;
    MethodCall* attach = new MethodCall(THIS_VALUE, "attachInterface",
                            2, THIS_VALUE, new LiteralExpression("DESCRIPTOR"));
    ctor->statements->Add(attach);
    this->elements.push_back(ctor);

    // asInterface
    make_as_interface(interfaceType);

    // asBinder
    Method* asBinder = new Method;
        asBinder->modifiers = PUBLIC;
        asBinder->returnType = IBINDER_TYPE;
        asBinder->name = "asBinder";
        asBinder->statements = new StatementBlock;
    asBinder->statements->Add(new ReturnStatement(THIS_VALUE));
    this->elements.push_back(asBinder);

    // onTransact
    this->transact_code = new Variable(INT_TYPE, "code");
    this->transact_data = new Variable(PARCEL_TYPE, "data");
    this->transact_reply = new Variable(PARCEL_TYPE, "reply");
    this->transact_flags = new Variable(INT_TYPE, "flags");
    Method* onTransact = new Method;
        onTransact->modifiers = PUBLIC | OVERRIDE;
        onTransact->returnType = BOOLEAN_TYPE;
        onTransact->name = "onTransact";
        onTransact->parameters.push_back(this->transact_code);
        onTransact->parameters.push_back(this->transact_data);
        onTransact->parameters.push_back(this->transact_reply);
        onTransact->parameters.push_back(this->transact_flags);
        onTransact->statements = new StatementBlock;
        onTransact->exceptions.push_back(REMOTE_EXCEPTION_TYPE);
    this->elements.push_back(onTransact);
    this->transact_switch = new SwitchStatement(this->transact_code);

    onTransact->statements->Add(this->transact_switch);
    MethodCall* superCall = new MethodCall(SUPER_VALUE, "onTransact", 4,
                                    this->transact_code, this->transact_data,
                                    this->transact_reply, this->transact_flags);
    onTransact->statements->Add(new ReturnStatement(superCall));
}

StubClass::~StubClass()
{
}

void
StubClass::make_as_interface(Type *interfaceType)
{
    Variable* obj = new Variable(IBINDER_TYPE, "obj");

    Method* m = new Method;
        m->comment = "/**\n * Cast an IBinder object into an ";
        m->comment += interfaceType->Name();
        m->comment += " interface,\n";
        m->comment += " * generating a proxy if needed.\n */";
        m->modifiers = PUBLIC | STATIC;
        m->returnType = interfaceType;
        m->name = "asInterface";
        m->parameters.push_back(obj);
        m->statements = new StatementBlock;

    IfStatement* ifstatement = new IfStatement();
        ifstatement->expression = new Comparison(obj, "==", NULL_VALUE);
        ifstatement->statements = new StatementBlock;
        ifstatement->statements->Add(new ReturnStatement(NULL_VALUE));
    m->statements->Add(ifstatement);

    // IInterface iin = obj.queryLocalInterface(DESCRIPTOR)
    MethodCall* queryLocalInterface = new MethodCall(obj, "queryLocalInterface");
    queryLocalInterface->arguments.push_back(new LiteralExpression("DESCRIPTOR"));
    IInterfaceType* iinType = new IInterfaceType();
    Variable *iin = new Variable(iinType, "iin");
    VariableDeclaration* iinVd = new VariableDeclaration(iin, queryLocalInterface, iinType);
    m->statements->Add(iinVd);

    // Ensure the instance type of the local object is as expected.
    // One scenario where this is needed is if another package (with a
    // different class loader) runs in the same process as the service.

    // if (iin != null && iin instanceof <interfaceType>) return (<interfaceType>) iin;
    Comparison* iinNotNull = new Comparison(iin, "!=", NULL_VALUE);
    Comparison* instOfCheck = new Comparison(iin, " instanceof ",
            new LiteralExpression(interfaceType->QualifiedName()));
    IfStatement* instOfStatement = new IfStatement();
        instOfStatement->expression = new Comparison(iinNotNull, "&&", instOfCheck);
        instOfStatement->statements = new StatementBlock;
        instOfStatement->statements->Add(new ReturnStatement(new Cast(interfaceType, iin)));
    m->statements->Add(instOfStatement);

    string proxyType = interfaceType->QualifiedName();
    proxyType += ".Stub.Proxy";
    NewExpression* ne = new NewExpression(NAMES.Find(proxyType));
    ne->arguments.push_back(obj);
    m->statements->Add(new ReturnStatement(ne));

    this->elements.push_back(m);
}



// =================================================
class ProxyClass : public Class
{
public:
    ProxyClass(Type* type, InterfaceType* interfaceType);
    virtual ~ProxyClass();

    Variable* mRemote;
    bool mOneWay;
};

ProxyClass::ProxyClass(Type* type, InterfaceType* interfaceType)
    :Class()
{
    this->modifiers = PRIVATE | STATIC;
    this->what = Class::CLASS;
    this->type = type;
    this->interfaces.push_back(interfaceType);

    mOneWay = interfaceType->OneWay();

    // IBinder mRemote
    mRemote = new Variable(IBINDER_TYPE, "mRemote");
    this->elements.push_back(new Field(PRIVATE, mRemote));

    // Proxy()
    Variable* remote = new Variable(IBINDER_TYPE, "remote");
    Method* ctor = new Method;
        ctor->name = "Proxy";
        ctor->statements = new StatementBlock;
        ctor->parameters.push_back(remote);
    ctor->statements->Add(new Assignment(mRemote, remote));
    this->elements.push_back(ctor);

    // IBinder asBinder()
    Method* asBinder = new Method;
        asBinder->modifiers = PUBLIC;
        asBinder->returnType = IBINDER_TYPE;
        asBinder->name = "asBinder";
        asBinder->statements = new StatementBlock;
    asBinder->statements->Add(new ReturnStatement(mRemote));
    this->elements.push_back(asBinder);
}

ProxyClass::~ProxyClass()
{
}

// =================================================
static string
gather_comments(extra_text_type* extra)
{
    string s;
    while (extra) {
        if (extra->which == SHORT_COMMENT) {
            s += extra->data;
        }
        else if (extra->which == LONG_COMMENT) {
            s += "/*";
            s += extra->data;
            s += "*/";
        }
        extra = extra->next;
    }
    return s;
}

static string
append(const char* a, const char* b)
{
    string s = a;
    s += b;
    return s;
}

static void
generate_new_array(Type* t, StatementBlock* addTo, Variable* v,
                            Variable* parcel)
{
    Variable* len = new Variable(INT_TYPE, v->name + "_length");
    addTo->Add(new VariableDeclaration(len, new MethodCall(parcel, "readInt")));
    IfStatement* lencheck = new IfStatement();
    lencheck->expression = new Comparison(len, "<", new LiteralExpression("0"));
    lencheck->statements->Add(new Assignment(v, NULL_VALUE));
    lencheck->elseif = new IfStatement();
    lencheck->elseif->statements->Add(new Assignment(v,
                new NewArrayExpression(t, len)));
    addTo->Add(lencheck);
}

static void
generate_write_to_parcel(Type* t, StatementBlock* addTo, Variable* v,
                            Variable* parcel, int flags)
{
    if (v->dimension == 0) {
        t->WriteToParcel(addTo, v, parcel, flags);
    }
    if (v->dimension == 1) {
        t->WriteArrayToParcel(addTo, v, parcel, flags);
    }
}

static void
generate_create_from_parcel(Type* t, StatementBlock* addTo, Variable* v,
                            Variable* parcel)
{
    if (v->dimension == 0) {
        t->CreateFromParcel(addTo, v, parcel);
    }
    if (v->dimension == 1) {
        t->CreateArrayFromParcel(addTo, v, parcel);
    }
}

static void
generate_read_from_parcel(Type* t, StatementBlock* addTo, Variable* v,
                            Variable* parcel)
{
    if (v->dimension == 0) {
        t->ReadFromParcel(addTo, v, parcel);
    }
    if (v->dimension == 1) {
        t->ReadArrayFromParcel(addTo, v, parcel);
    }
}


static void
generate_method(const method_type* method, Class* interface,
                    StubClass* stubClass, ProxyClass* proxyClass, int index)
{
    arg_type* arg;
    int i;
    bool hasOutParams = false;

    const bool oneway = proxyClass->mOneWay || method->oneway;

    // == the TRANSACT_ constant =============================================
    string transactCodeName = "TRANSACTION_";
    transactCodeName += method->name.data;

    char transactCodeValue[50];
    sprintf(transactCodeValue, "(IBinder.FIRST_CALL_TRANSACTION + %d)", index);

    Field* transactCode = new Field(STATIC | FINAL,
                            new Variable(INT_TYPE, transactCodeName));
    transactCode->value = transactCodeValue;
    stubClass->elements.push_back(transactCode);

    // == the declaration in the interface ===================================
    Method* decl = new Method;
        decl->comment = gather_comments(method->comments_token->extra);
        decl->modifiers = PUBLIC;
        decl->returnType = NAMES.Search(method->type.type.data);
        decl->returnTypeDimension = method->type.dimension;
        decl->name = method->name.data;

    arg = method->args;
    while (arg != NULL) {
        decl->parameters.push_back(new Variable(
                            NAMES.Search(arg->type.type.data), arg->name.data,
                            arg->type.dimension));
        arg = arg->next;
    }

    decl->exceptions.push_back(REMOTE_EXCEPTION_TYPE);

    interface->elements.push_back(decl);

    // == the stub method ====================================================

    Case* c = new Case(transactCodeName);

    MethodCall* realCall = new MethodCall(THIS_VALUE, method->name.data);

    // interface token validation is the very first thing we do
    c->statements->Add(new MethodCall(stubClass->transact_data,
            "enforceInterface", 1, new LiteralExpression("DESCRIPTOR")));

    // args
    VariableFactory stubArgs("_arg");
    arg = method->args;
    while (arg != NULL) {
        Type* t = NAMES.Search(arg->type.type.data);
        Variable* v = stubArgs.Get(t);
        v->dimension = arg->type.dimension;

        c->statements->Add(new VariableDeclaration(v));

        if (convert_direction(arg->direction.data) & IN_PARAMETER) {
            generate_create_from_parcel(t, c->statements, v,
                    stubClass->transact_data);
        } else {
            if (arg->type.dimension == 0) {
                c->statements->Add(new Assignment(
                                                v, new NewExpression(v->type)));
            }
            else if (arg->type.dimension == 1) {
                generate_new_array(v->type, c->statements, v,
                        stubClass->transact_data);
            }
            else {
                fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__,
                        __LINE__);
            }
        }

        realCall->arguments.push_back(v);

        arg = arg->next;
    }

    // the real call
    Variable* _result = NULL;
    if (0 == strcmp(method->type.type.data, "void")) {
        c->statements->Add(realCall);

        if (!oneway) {
            // report that there were no exceptions
            MethodCall* ex = new MethodCall(stubClass->transact_reply,
                    "writeNoException", 0);
            c->statements->Add(ex);
        }
    } else {
        _result = new Variable(decl->returnType, "_result",
                                decl->returnTypeDimension);
        c->statements->Add(new VariableDeclaration(_result, realCall));

        if (!oneway) {
            // report that there were no exceptions
            MethodCall* ex = new MethodCall(stubClass->transact_reply,
                    "writeNoException", 0);
            c->statements->Add(ex);
        }

        // marshall the return value
        generate_write_to_parcel(decl->returnType, c->statements, _result,
                                    stubClass->transact_reply,
                                    Type::PARCELABLE_WRITE_RETURN_VALUE);
    }

    // out parameters
    i = 0;
    arg = method->args;
    while (arg != NULL) {
        Type* t = NAMES.Search(arg->type.type.data);
        Variable* v = stubArgs.Get(i++);

        if (convert_direction(arg->direction.data) & OUT_PARAMETER) {
            generate_write_to_parcel(t, c->statements, v,
                                stubClass->transact_reply,
                                Type::PARCELABLE_WRITE_RETURN_VALUE);
            hasOutParams = true;
        }

        arg = arg->next;
    }

    // return true
    c->statements->Add(new ReturnStatement(TRUE_VALUE));
    stubClass->transact_switch->cases.push_back(c);

    // == the proxy method ===================================================
    Method* proxy = new Method;
        proxy->comment = gather_comments(method->comments_token->extra);
        proxy->modifiers = PUBLIC;
        proxy->returnType = NAMES.Search(method->type.type.data);
        proxy->returnTypeDimension = method->type.dimension;
        proxy->name = method->name.data;
        proxy->statements = new StatementBlock;
        arg = method->args;
        while (arg != NULL) {
            proxy->parameters.push_back(new Variable(
                            NAMES.Search(arg->type.type.data), arg->name.data,
                            arg->type.dimension));
            arg = arg->next;
        }
        proxy->exceptions.push_back(REMOTE_EXCEPTION_TYPE);
    proxyClass->elements.push_back(proxy);

    // the parcels
    Variable* _data = new Variable(PARCEL_TYPE, "_data");
    proxy->statements->Add(new VariableDeclaration(_data,
                                new MethodCall(PARCEL_TYPE, "obtain")));
    Variable* _reply = NULL;
    if (!oneway) {
        _reply = new Variable(PARCEL_TYPE, "_reply");
        proxy->statements->Add(new VariableDeclaration(_reply,
                                    new MethodCall(PARCEL_TYPE, "obtain")));
    }

    // the return value
    _result = NULL;
    if (0 != strcmp(method->type.type.data, "void")) {
        _result = new Variable(proxy->returnType, "_result",
                method->type.dimension);
        proxy->statements->Add(new VariableDeclaration(_result));
    }

    // try and finally
    TryStatement* tryStatement = new TryStatement();
    proxy->statements->Add(tryStatement);
    FinallyStatement* finallyStatement = new FinallyStatement();
    proxy->statements->Add(finallyStatement);

    // the interface identifier token: the DESCRIPTOR constant, marshalled as a string
    tryStatement->statements->Add(new MethodCall(_data, "writeInterfaceToken",
            1, new LiteralExpression("DESCRIPTOR")));

    // the parameters
    arg = method->args;
    while (arg != NULL) {
        Type* t = NAMES.Search(arg->type.type.data);
        Variable* v = new Variable(t, arg->name.data, arg->type.dimension);
        int dir = convert_direction(arg->direction.data);
        if (dir == OUT_PARAMETER && arg->type.dimension != 0) {
            IfStatement* checklen = new IfStatement();
            checklen->expression = new Comparison(v, "==", NULL_VALUE);
            checklen->statements->Add(new MethodCall(_data, "writeInt", 1,
                        new LiteralExpression("-1")));
            checklen->elseif = new IfStatement();
            checklen->elseif->statements->Add(new MethodCall(_data, "writeInt",
                        1, new FieldVariable(v, "length")));
            tryStatement->statements->Add(checklen);
        }
        else if (dir & IN_PARAMETER) {
            generate_write_to_parcel(t, tryStatement->statements, v, _data, 0);
        }
        arg = arg->next;
    }

    // the transact call
    MethodCall* call = new MethodCall(proxyClass->mRemote, "transact", 4,
                            new LiteralExpression("Stub." + transactCodeName),
                            _data, _reply ? _reply : NULL_VALUE,
                            new LiteralExpression(
                                oneway ? "IBinder.FLAG_ONEWAY" : "0"));
    tryStatement->statements->Add(call);

    // throw back exceptions.
    if (_reply) {
        MethodCall* ex = new MethodCall(_reply, "readException", 0);
        tryStatement->statements->Add(ex);
    }

    // returning and cleanup
    if (_reply != NULL) {
        if (_result != NULL) {
            generate_create_from_parcel(proxy->returnType,
                                    tryStatement->statements, _result, _reply);
        }

        // the out/inout parameters
        arg = method->args;
        while (arg != NULL) {
            Type* t = NAMES.Search(arg->type.type.data);
            Variable* v = new Variable(t, arg->name.data, arg->type.dimension);
            if (convert_direction(arg->direction.data) & OUT_PARAMETER) {
                generate_read_from_parcel(t, tryStatement->statements,
                                            v, _reply);
            }
            arg = arg->next;
        }

        finallyStatement->statements->Add(new MethodCall(_reply, "recycle"));
    }
    finallyStatement->statements->Add(new MethodCall(_data, "recycle"));

    if (_result != NULL) {
        proxy->statements->Add(new ReturnStatement(_result));
    }
}

static void
generate_interface_descriptors(StubClass* stub, ProxyClass* proxy)
{
    // the interface descriptor transaction handler
    Case* c = new Case("INTERFACE_TRANSACTION");
    c->statements->Add(new MethodCall(stub->transact_reply, "writeString",
            1, new LiteralExpression("DESCRIPTOR")));
    c->statements->Add(new ReturnStatement(TRUE_VALUE));
    stub->transact_switch->cases.push_back(c);

    // and the proxy-side method returning the descriptor directly
    Method* getDesc = new Method;
    getDesc->modifiers = PUBLIC;
    getDesc->returnType = STRING_TYPE;
    getDesc->returnTypeDimension = 0;
    getDesc->name = "getInterfaceDescriptor";
    getDesc->statements = new StatementBlock;
    getDesc->statements->Add(new ReturnStatement(new LiteralExpression("DESCRIPTOR")));
    proxy->elements.push_back(getDesc);
}

static Class*
generate_interface_class(const interface_type* iface)
{
    InterfaceType* interfaceType = static_cast<InterfaceType*>(
        NAMES.Find(iface->package, iface->name.data));

    // the interface class
    Class* interface = new Class;
        interface->comment = gather_comments(iface->comments_token->extra);
        interface->modifiers = PUBLIC;
        interface->what = Class::INTERFACE;
        interface->type = interfaceType;
        interface->interfaces.push_back(IINTERFACE_TYPE);

    // the stub inner class
    StubClass* stub = new StubClass(
        NAMES.Find(iface->package, append(iface->name.data, ".Stub").c_str()),
        interfaceType);
    interface->elements.push_back(stub);

    // the proxy inner class
    ProxyClass* proxy = new ProxyClass(
        NAMES.Find(iface->package,
                         append(iface->name.data, ".Stub.Proxy").c_str()),
        interfaceType);
    stub->elements.push_back(proxy);

    // stub and proxy support for getInterfaceDescriptor()
    generate_interface_descriptors(stub, proxy);

    // all the declared methods of the interface
    int index = 0;
    interface_item_type* item = iface->interface_items;
    while (item != NULL) {
        if (item->item_type == METHOD_TYPE) {
            generate_method((method_type*)item, interface, stub, proxy, index);
        }
        item = item->next;
        index++;
    }

    return interface;
}

int
generate_java(const string& filename, const string& originalSrc,
                interface_type* iface)
{
    Document* document = new Document;
        document->comment = "";
        if (iface->package) document->package = iface->package;
        document->originalSrc = originalSrc;
        document->classes.push_back(generate_interface_class(iface));

//    printf("outputting... filename=%s\n", filename.c_str());
    FILE* to;
    if (filename == "-") {
        to = stdout;
    } else {
       /* open file in binary mode to ensure that the tool produces the
        * same output on all platforms !!
        */
        to = fopen(filename.c_str(), "wb");
        if (to == NULL) {
            fprintf(stderr, "unable to open %s for write\n", filename.c_str());
            return 1;
        }
    }

    document->Write(to);

    fclose(to);
    return 0;
}

