/**
 * All rights reserved. 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 org.jivesoftware.smackx.bytestreams.socks5.packet;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;

import org.jivesoftware.smack.packet.IQ;
import org.jivesoftware.smack.packet.PacketExtension;

/**
 * A packet representing part of a SOCKS5 Bytestream negotiation.
 * 
 * @author Alexander Wenckus
 */
public class Bytestream extends IQ {

    private String sessionID;

    private Mode mode = Mode.tcp;

    private final List<StreamHost> streamHosts = new ArrayList<StreamHost>();

    private StreamHostUsed usedHost;

    private Activate toActivate;

    /**
     * The default constructor
     */
    public Bytestream() {
        super();
    }

    /**
     * A constructor where the session ID can be specified.
     * 
     * @param SID The session ID related to the negotiation.
     * @see #setSessionID(String)
     */
    public Bytestream(final String SID) {
        super();
        setSessionID(SID);
    }

    /**
     * Set the session ID related to the bytestream. The session ID is a unique identifier used to
     * differentiate between stream negotiations.
     * 
     * @param sessionID the unique session ID that identifies the transfer.
     */
    public void setSessionID(final String sessionID) {
        this.sessionID = sessionID;
    }

    /**
     * Returns the session ID related to the bytestream negotiation.
     * 
     * @return Returns the session ID related to the bytestream negotiation.
     * @see #setSessionID(String)
     */
    public String getSessionID() {
        return sessionID;
    }

    /**
     * Set the transport mode. This should be put in the initiation of the interaction.
     * 
     * @param mode the transport mode, either UDP or TCP
     * @see Mode
     */
    public void setMode(final Mode mode) {
        this.mode = mode;
    }

    /**
     * Returns the transport mode.
     * 
     * @return Returns the transport mode.
     * @see #setMode(Mode)
     */
    public Mode getMode() {
        return mode;
    }

    /**
     * Adds a potential stream host that the remote user can connect to to receive the file.
     * 
     * @param JID The JID of the stream host.
     * @param address The internet address of the stream host.
     * @return The added stream host.
     */
    public StreamHost addStreamHost(final String JID, final String address) {
        return addStreamHost(JID, address, 0);
    }

    /**
     * Adds a potential stream host that the remote user can connect to to receive the file.
     * 
     * @param JID The JID of the stream host.
     * @param address The internet address of the stream host.
     * @param port The port on which the remote host is seeking connections.
     * @return The added stream host.
     */
    public StreamHost addStreamHost(final String JID, final String address, final int port) {
        StreamHost host = new StreamHost(JID, address);
        host.setPort(port);
        addStreamHost(host);

        return host;
    }

    /**
     * Adds a potential stream host that the remote user can transfer the file through.
     * 
     * @param host The potential stream host.
     */
    public void addStreamHost(final StreamHost host) {
        streamHosts.add(host);
    }

    /**
     * Returns the list of stream hosts contained in the packet.
     * 
     * @return Returns the list of stream hosts contained in the packet.
     */
    public Collection<StreamHost> getStreamHosts() {
        return Collections.unmodifiableCollection(streamHosts);
    }

    /**
     * Returns the stream host related to the given JID, or null if there is none.
     * 
     * @param JID The JID of the desired stream host.
     * @return Returns the stream host related to the given JID, or null if there is none.
     */
    public StreamHost getStreamHost(final String JID) {
        if (JID == null) {
            return null;
        }
        for (StreamHost host : streamHosts) {
            if (host.getJID().equals(JID)) {
                return host;
            }
        }

        return null;
    }

    /**
     * Returns the count of stream hosts contained in this packet.
     * 
     * @return Returns the count of stream hosts contained in this packet.
     */
    public int countStreamHosts() {
        return streamHosts.size();
    }

    /**
     * Upon connecting to the stream host the target of the stream replies to the initiator with the
     * JID of the SOCKS5 host that they used.
     * 
     * @param JID The JID of the used host.
     */
    public void setUsedHost(final String JID) {
        this.usedHost = new StreamHostUsed(JID);
    }

    /**
     * Returns the SOCKS5 host connected to by the remote user.
     * 
     * @return Returns the SOCKS5 host connected to by the remote user.
     */
    public StreamHostUsed getUsedHost() {
        return usedHost;
    }

    /**
     * Returns the activate element of the packet sent to the proxy host to verify the identity of
     * the initiator and match them to the appropriate stream.
     * 
     * @return Returns the activate element of the packet sent to the proxy host to verify the
     *         identity of the initiator and match them to the appropriate stream.
     */
    public Activate getToActivate() {
        return toActivate;
    }

    /**
     * Upon the response from the target of the used host the activate packet is sent to the SOCKS5
     * proxy. The proxy will activate the stream or return an error after verifying the identity of
     * the initiator, using the activate packet.
     * 
     * @param targetID The JID of the target of the file transfer.
     */
    public void setToActivate(final String targetID) {
        this.toActivate = new Activate(targetID);
    }

    public String getChildElementXML() {
        StringBuilder buf = new StringBuilder();

        buf.append("<query xmlns=\"http://jabber.org/protocol/bytestreams\"");
        if (this.getType().equals(IQ.Type.SET)) {
            if (getSessionID() != null) {
                buf.append(" sid=\"").append(getSessionID()).append("\"");
            }
            if (getMode() != null) {
                buf.append(" mode = \"").append(getMode()).append("\"");
            }
            buf.append(">");
            if (getToActivate() == null) {
                for (StreamHost streamHost : getStreamHosts()) {
                    buf.append(streamHost.toXML());
                }
            }
            else {
                buf.append(getToActivate().toXML());
            }
        }
        else if (this.getType().equals(IQ.Type.RESULT)) {
            buf.append(">");
            if (getUsedHost() != null) {
                buf.append(getUsedHost().toXML());
            }
            // A result from the server can also contain stream hosts
            else if (countStreamHosts() > 0) {
                for (StreamHost host : streamHosts) {
                    buf.append(host.toXML());
                }
            }
        }
        else if (this.getType().equals(IQ.Type.GET)) {
            return buf.append("/>").toString();
        }
        else {
            return null;
        }
        buf.append("</query>");

        return buf.toString();
    }

    /**
     * Packet extension that represents a potential SOCKS5 proxy for the file transfer. Stream hosts
     * are forwarded to the target of the file transfer who then chooses and connects to one.
     * 
     * @author Alexander Wenckus
     */
    public static class StreamHost implements PacketExtension {

        public static String NAMESPACE = "";

        public static String ELEMENTNAME = "streamhost";

        private final String JID;

        private final String addy;

        private int port = 0;

        /**
         * Default constructor.
         * 
         * @param JID The JID of the stream host.
         * @param address The internet address of the stream host.
         */
        public StreamHost(final String JID, final String address) {
            this.JID = JID;
            this.addy = address;
        }

        /**
         * Returns the JID of the stream host.
         * 
         * @return Returns the JID of the stream host.
         */
        public String getJID() {
            return JID;
        }

        /**
         * Returns the internet address of the stream host.
         * 
         * @return Returns the internet address of the stream host.
         */
        public String getAddress() {
            return addy;
        }

        /**
         * Sets the port of the stream host.
         * 
         * @param port The port on which the potential stream host would accept the connection.
         */
        public void setPort(final int port) {
            this.port = port;
        }

        /**
         * Returns the port on which the potential stream host would accept the connection.
         * 
         * @return Returns the port on which the potential stream host would accept the connection.
         */
        public int getPort() {
            return port;
        }

        public String getNamespace() {
            return NAMESPACE;
        }

        public String getElementName() {
            return ELEMENTNAME;
        }

        public String toXML() {
            StringBuilder buf = new StringBuilder();

            buf.append("<").append(getElementName()).append(" ");
            buf.append("jid=\"").append(getJID()).append("\" ");
            buf.append("host=\"").append(getAddress()).append("\" ");
            if (getPort() != 0) {
                buf.append("port=\"").append(getPort()).append("\"");
            }
            else {
                buf.append("zeroconf=\"_jabber.bytestreams\"");
            }
            buf.append("/>");

            return buf.toString();
        }
    }

    /**
     * After selected a SOCKS5 stream host and successfully connecting, the target of the file
     * transfer returns a byte stream packet with the stream host used extension.
     * 
     * @author Alexander Wenckus
     */
    public static class StreamHostUsed implements PacketExtension {

        public String NAMESPACE = "";

        public static String ELEMENTNAME = "streamhost-used";

        private final String JID;

        /**
         * Default constructor.
         * 
         * @param JID The JID of the selected stream host.
         */
        public StreamHostUsed(final String JID) {
            this.JID = JID;
        }

        /**
         * Returns the JID of the selected stream host.
         * 
         * @return Returns the JID of the selected stream host.
         */
        public String getJID() {
            return JID;
        }

        public String getNamespace() {
            return NAMESPACE;
        }

        public String getElementName() {
            return ELEMENTNAME;
        }

        public String toXML() {
            StringBuilder buf = new StringBuilder();
            buf.append("<").append(getElementName()).append(" ");
            buf.append("jid=\"").append(getJID()).append("\" ");
            buf.append("/>");
            return buf.toString();
        }
    }

    /**
     * The packet sent by the stream initiator to the stream proxy to activate the connection.
     * 
     * @author Alexander Wenckus
     */
    public static class Activate implements PacketExtension {

        public String NAMESPACE = "";

        public static String ELEMENTNAME = "activate";

        private final String target;

        /**
         * Default constructor specifying the target of the stream.
         * 
         * @param target The target of the stream.
         */
        public Activate(final String target) {
            this.target = target;
        }

        /**
         * Returns the target of the activation.
         * 
         * @return Returns the target of the activation.
         */
        public String getTarget() {
            return target;
        }

        public String getNamespace() {
            return NAMESPACE;
        }

        public String getElementName() {
            return ELEMENTNAME;
        }

        public String toXML() {
            StringBuilder buf = new StringBuilder();
            buf.append("<").append(getElementName()).append(">");
            buf.append(getTarget());
            buf.append("</").append(getElementName()).append(">");
            return buf.toString();
        }
    }

    /**
     * The stream can be either a TCP stream or a UDP stream.
     * 
     * @author Alexander Wenckus
     */
    public enum Mode {

        /**
         * A TCP based stream.
         */
        tcp,

        /**
         * A UDP based stream.
         */
        udp;

        public static Mode fromName(String name) {
            Mode mode;
            try {
                mode = Mode.valueOf(name);
            }
            catch (Exception ex) {
                mode = tcp;
            }

            return mode;
        }
    }
}
