package com.zepchat.core.transport.messaging;


import android.util.Log;
import com.zepchat.core.ZEPCore;
import com.zepchat.core.transport.ZEPMessagingTransport;
import com.zepchat.core.data.Message;
import com.zepchat.core.data.User;
import zutil.io.StringOutputStream;
import zutil.net.http.HttpHeaderParser;
import zutil.net.http.HttpPrintStream;
import zutil.net.ssdp.SSDPClient;
import zutil.net.ssdp.SSDPServer;
import zutil.net.ssdp.StandardSSDPInfo;
import zutil.net.threaded.ThreadedUDPNetwork;
import zutil.net.threaded.ThreadedUDPNetworkThread;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.InetAddress;
import java.util.HashMap;

/**
 * Created by Ziver on 2014-11-06.
 */
public class HttpMessagingTransport extends ThreadedUDPNetwork implements ThreadedUDPNetworkThread, ZEPMessagingTransport{
    public static final int PORT = 1901;

    private final HashMap<String, String> headers;
    private MessageListener msgListener;
    private HashMap<String, InetAddress> userAddresses;
    private User localUser;
    private ZEPCore core;

    public HttpMessagingTransport(ZEPCore core, User localUser) throws IOException{
        super( null, PORT );
        super.setThread( this );

        this.localUser = localUser;
        this.core = core;

        headers = new HashMap<String, String>();
        headers.put("Alias", localUser.getAlias());
        headers.put("PublicKey", localUser.getPublicKey());

        userAddresses = new HashMap<String, InetAddress>();
    }


    @Override
    public void setMessageListener(MessageListener msgListener) {
        this.msgListener = msgListener;
    }

    @Override
    public void sendMessage(User remoteUser, String message) {
        send(remoteUser, message);
    }


    protected void send(final User remoteUser, final String message){
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    StringOutputStream response = new StringOutputStream();
                    HttpPrintStream http = new HttpPrintStream( response );
                    http.setStatusCode(200);
                    http.setHeader("From", localUser.getPublicKey());
                    http.setHeader("To", remoteUser.getPublicKey());
                    http.setHeader("Message", message);
                    http.flush();

                    String strData = response.toString();
                    Log.d("IpMessageServer", "Send Message:\n" + strData);
                    byte[] data = strData.getBytes();
                    DatagramPacket packet = new DatagramPacket(
                            data, data.length,
                            userAddresses.get(remoteUser.getPublicKey()),
                            PORT);

                    send(packet);

                    http.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }).start();

    }

    @Override
    public void receivedPacket(DatagramPacket packet, ThreadedUDPNetwork network) {
        try {
            HttpHeaderParser header = new HttpHeaderParser( new String( packet.getData() ) );
            if(core.getRemoteUser(header.getHeader("From")) == null){
                User user = new User(
                        "Unknown",
                        header.getHeader("From"));
                userAddresses.put(user.getPublicKey(), packet.getAddress());
            }
            Message msg = new Message(
                    core.getRemoteUser(header.getHeader("From")),
                    header.getHeader("Message")
            );
            if(msgListener != null) {
                msgListener.newMessage(msg);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


}
