/*
 ** Copyright 2011, 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.
 */

package com.android.glesv2debugger;

import com.android.glesv2debugger.DebuggerMessage.Message.Type;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.EOFException;
import java.io.IOException;
import java.net.Socket;
import java.util.ArrayList;
import java.util.HashMap;

public class MessageQueue implements Runnable {

    boolean running = false;
    Thread thread = null;
    ArrayList<DebuggerMessage.Message> complete = new ArrayList<DebuggerMessage.Message>();
    ArrayList<DebuggerMessage.Message> commands = new ArrayList<DebuggerMessage.Message>();
    SampleView sampleView;

    HashMap<Integer, GLServerVertex> serversVertex = new HashMap<Integer, GLServerVertex>();

    public MessageQueue(SampleView sampleView) {
        this.sampleView = sampleView;
    }

    public void Start() {
        if (running)
            return;
        running = true;
        thread = new Thread(this);
        thread.start();
    }

    public void Stop() {
        if (!running)
            return;
        running = false;
    }

    public boolean IsRunning() {
        return running;
    }

    void SendCommands(final DataOutputStream dos, final int contextId) throws IOException {
        synchronized (commands) {
            for (int i = 0; i < commands.size(); i++) {
                DebuggerMessage.Message command = commands.get(i);
                if (command.getContextId() == contextId || contextId == 0) { // FIXME:
                                                                             // proper
                                                                             // context
                                                                             // id
                    SendMessage(dos, command);
                    commands.remove(i);
                    i--;
                }
            }
        }
        SendResponse(dos, contextId, DebuggerMessage.Message.Function.SKIP);
    }

    public void AddCommand(DebuggerMessage.Message command) {
        synchronized (commands) {
            commands.add(command);
        }
    }

    @Override
    public void run() {
        Socket socket = new Socket();
        DataInputStream dis = null;
        DataOutputStream dos = null;
        HashMap<Integer, ArrayList<DebuggerMessage.Message>> incoming = new HashMap<Integer, ArrayList<DebuggerMessage.Message>>();
        try {
            socket.connect(new java.net.InetSocketAddress("127.0.0.1", 5039));
            dis = new DataInputStream(socket.getInputStream());
            dos = new DataOutputStream(socket.getOutputStream());
        } catch (Exception e) {
            running = false;
            Error(e);
        }

        // try {
        while (running) {
            DebuggerMessage.Message msg = null;
            if (incoming.size() > 0) { // find queued incoming
                for (ArrayList<DebuggerMessage.Message> messages : incoming
                            .values())
                    if (messages.size() > 0) {
                        msg = messages.get(0);
                        messages.remove(0);
                        break;
                    }
            }
            if (null == msg) { // get incoming from network
                try {
                    msg = ReadMessage(dis);
                    if (msg.getExpectResponse()) {
                        if (msg.getType() == Type.BeforeCall)
                            SendResponse(dos, msg.getContextId(),
                                    DebuggerMessage.Message.Function.CONTINUE);
                        else if (msg.getType() == Type.AfterCall)
                            // after GL function call
                            SendCommands(dos, 0); // FIXME: proper context id
                        // SendResponse(dos, msg.getContextId(),
                        // DebuggerMessage.Message.Function.SKIP);
                        else if (msg.getType() == Type.Response)
                            assert true;
                        else
                            assert false;
                    }
                } catch (IOException e) {
                    Error(e);
                    running = false;
                    break;
                }
            }

            int contextId = msg.getContextId();
            if (!incoming.containsKey(contextId))
                incoming.put(contextId,
                            new ArrayList<DebuggerMessage.Message>());

            // FIXME: the expected sequence will change for interactive mode
            while (msg.getType() == Type.BeforeCall) {
                DebuggerMessage.Message next = null;
                // get existing message part for this context
                ArrayList<DebuggerMessage.Message> messages = incoming
                            .get(contextId);
                if (messages.size() > 0) {
                    next = messages.get(0);
                    messages.remove(0);
                }
                if (null == next) { // read new part for message
                    try {
                        next = ReadMessage(dis);

                        if (next.getExpectResponse()) {
                            if (next.getType() == Type.BeforeCall)
                                SendResponse(
                                        dos,
                                        next.getContextId(),
                                        DebuggerMessage.Message.Function.CONTINUE);
                            else if (next.getType() == Type.AfterCall)
                                SendCommands(dos, 0); // FIXME: proper context
                                                      // id
                            else if (msg.getType() == Type.Response)
                                assert true;
                            else
                                assert false;
                        }
                    } catch (IOException e) {
                        Error(e);
                        running = false;
                        break;
                    }

                    if (next.getContextId() != contextId) {
                        // message part not for this context
                        if (!incoming.containsKey(next.getContextId()))
                            incoming.put(
                                        next.getContextId(),
                                        new ArrayList<DebuggerMessage.Message>());
                        incoming.get(next.getContextId()).add(next);
                        continue;
                    }
                }

                DebuggerMessage.Message.Builder builder = msg.toBuilder();
                // builder.mergeFrom(next); seems to merge incorrectly
                if (next.hasRet())
                    builder.setRet(next.getRet());
                if (next.hasTime())
                    builder.setTime(next.getTime());
                if (next.hasData())
                    builder.setData(next.getData());
                builder.setType(next.getType());
                msg = builder.build();
            }

            GLServerVertex serverVertex = serversVertex.get(msg.getContextId());
            if (null == serverVertex) {
                serverVertex = new GLServerVertex();
                serversVertex.put(msg.getContextId(), serverVertex);
            }

            // forward message to synchronize state
            switch (msg.getFunction()) {
                case glBindBuffer:
                    serverVertex.glBindBuffer(msg);
                    break;
                case glBufferData:
                    serverVertex.glBufferData(msg);
                    break;
                case glBufferSubData:
                    serverVertex.glBufferSubData(msg);
                    break;
                case glDeleteBuffers:
                    serverVertex.glDeleteBuffers(msg);
                    break;
                case glDrawArrays:
                    if (msg.hasArg7())
                        msg = serverVertex.glDrawArrays(msg);
                    break;
                case glDrawElements:
                    if (msg.hasArg7())
                        msg = serverVertex.glDrawElements(msg);
                    break;
                case glDisableVertexAttribArray:
                    serverVertex.glDisableVertexAttribArray(msg);
                    break;
                case glEnableVertexAttribArray:
                    serverVertex.glEnableVertexAttribArray(msg);
                    break;
                case glGenBuffers:
                    serverVertex.glGenBuffers(msg);
                    break;
                case glVertexAttribPointer:
                    serverVertex.glVertexAttribPointer(msg);
                    break;
                case glVertexAttrib1f:
                    serverVertex.glVertexAttrib1f(msg);
                    break;
                case glVertexAttrib1fv:
                    serverVertex.glVertexAttrib1fv(msg);
                    break;
                case glVertexAttrib2f:
                    serverVertex.glVertexAttrib2f(msg);
                    break;
                case glVertexAttrib2fv:
                    serverVertex.glVertexAttrib2fv(msg);
                    break;
                case glVertexAttrib3f:
                    serverVertex.glVertexAttrib3f(msg);
                    break;
                case glVertexAttrib3fv:
                    serverVertex.glVertexAttrib3fv(msg);
                    break;
                case glVertexAttrib4f:
                    serverVertex.glVertexAttrib4f(msg);
                    break;
                case glVertexAttrib4fv:
                    serverVertex.glVertexAttrib4fv(msg);
                    break;
            }

            synchronized (complete) {
                complete.add(msg);
            }
        }

        try {
            socket.close();
        } catch (IOException e) {
            Error(e);
            running = false;
        }
        // } catch (Exception e) {
        // Error(e);
        // running = false;
        // }
    }

    public DebuggerMessage.Message RemoveMessage(int contextId) {
        synchronized (complete) {
            if (complete.size() == 0)
                return null;
            if (0 == contextId) // get a message of any
            {
                DebuggerMessage.Message msg = complete.get(0);
                complete.remove(0);
                return msg;
            }
            for (int i = 0; i < complete.size(); i++) {
                DebuggerMessage.Message msg = complete.get(i);
                if (msg.getContextId() == contextId) {
                    complete.remove(i);
                    return msg;
                }
            }
        }
        return null;
    }

    DebuggerMessage.Message ReadMessage(final DataInputStream dis)
            throws IOException {
        int len = 0;
        try {
            len = dis.readInt();
        } catch (EOFException e) {
            Error(new Exception("EOF"));
        }
        byte[] buffer = new byte[len];
        int readLen = 0;
        while (readLen < len) {
            int read = -1;
            try {
                read = dis.read(buffer, readLen, len - readLen);
            } catch (EOFException e) {
                Error(new Exception("EOF"));
            }
            if (read < 0) {
                Error(new Exception("read length = " + read));
                return null;
            } else
                readLen += read;
        }
        DebuggerMessage.Message msg = DebuggerMessage.Message.parseFrom(buffer);
        return msg;
    }

    void SendMessage(final DataOutputStream dos, final DebuggerMessage.Message message)
            throws IOException {
        final byte[] data = message.toByteArray();
        dos.writeInt(data.length);
        dos.write(data);
    }

    void SendResponse(final DataOutputStream dos, final int contextId,
            final DebuggerMessage.Message.Function function) throws IOException {
        DebuggerMessage.Message.Builder builder = DebuggerMessage.Message
                .newBuilder();
        builder.setContextId(contextId);
        builder.setFunction(function);
        builder.setType(Type.Response);
        builder.setExpectResponse(false);
        SendMessage(dos, builder.build());
    }

    void Error(Exception e) {
        sampleView.showError(e);
    }
}
