package com.zepchat.core.transport.discovery;


import com.zepchat.core.ZEPCore;
import com.zepchat.core.transport.ZEPDiscoveryTransport;
import com.zepchat.core.data.User;
import zutil.net.ssdp.*;

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

/**
 * Created by Ziver on 2014-11-06.
 */
public class SSDPDiscoveryTransport implements SSDPClient.SSDPServiceListener, ZEPDiscoveryTransport{
    private final HashMap<String, String> headers;
    private SSDPClient ssdpClient;
    private SSDPServer ssdpServer;
    private HashMap<String, InetAddress> userAddresses;
    private User localUser;
    private ZEPCore core;
    private UserStatusListener userListener;

    public SSDPDiscoveryTransport(ZEPCore core, User localUser){
        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>();
    }

    public void setUserStatusListener(UserStatusListener userListener){
        this.userListener = userListener;
    }


    public void start(){
        try {
            StandardSSDPInfo service = new StandardSSDPInfo();
            service.setLocation("everywhere");
            service.setST("zep:discover");
            service.setHeaders(headers);
            ssdpServer = new SSDPServer();
            ssdpServer.addService(service);
            ssdpServer.start();

            ssdpClient = new SSDPClient();
            ssdpClient.setListener(this);
            ssdpClient.start();
            scan();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void close(){
        ssdpClient.close();
    }

    public void scan(){
        new Thread(new Runnable(){
            @Override
            public void run() {
                ssdpClient.requestService("zep:discover", headers);
            }
        }).start();
    }

    @Override
    public void newService(StandardSSDPInfo standardSSDPInfo) {
        User user = new User(
                standardSSDPInfo.getHeader("Alias"),
                standardSSDPInfo.getHeader("PublicKey"));
        userAddresses.put(user.getPublicKey(), standardSSDPInfo.getInetAddress());
        if(userListener != null) {
            userListener.addRemoteUser(user);
        }
    }

}
