//
//  ========================================================================
//  Copyright (c) 1995-2017 Mort Bay Consulting Pty. Ltd.
//  ------------------------------------------------------------------------
//  All rights reserved. This program and the accompanying materials
//  are made available under the terms of the Eclipse Public License v1.0
//  and Apache License v2.0 which accompanies this distribution.
//
//      The Eclipse Public License is available at
//      http://www.eclipse.org/legal/epl-v10.html
//
//      The Apache License v2.0 is available at
//      http://www.opensource.org/licenses/apache2.0.php
//
//  You may elect to redistribute this code under either of these licenses.
//  ========================================================================
//

package org.eclipse.jetty.spdy.server.proxy;

import java.net.InetSocketAddress;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import org.eclipse.jetty.spdy.api.GoAwayResultInfo;
import org.eclipse.jetty.spdy.api.PingResultInfo;
import org.eclipse.jetty.spdy.api.RstInfo;
import org.eclipse.jetty.spdy.api.Session;
import org.eclipse.jetty.spdy.api.Stream;
import org.eclipse.jetty.spdy.api.StreamFrameListener;
import org.eclipse.jetty.spdy.api.StreamStatus;
import org.eclipse.jetty.spdy.api.SynInfo;
import org.eclipse.jetty.spdy.api.server.ServerSessionFrameListener;
import org.eclipse.jetty.spdy.http.HTTPSPDYHeader;
import org.eclipse.jetty.util.Callback;
import org.eclipse.jetty.util.Fields;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;

/**
 * <p>{@link ProxyEngineSelector} is the main entry point for push stream events of a jetty SPDY proxy. It receives the
 * push stream frames from the clients, checks if there's an appropriate {@link ProxyServerInfo} for the given target
 * host and forwards the push to a {@link ProxyEngine} for the protocol defined in {@link ProxyServerInfo}.</p>
 *
 * <p>If no {@link ProxyServerInfo} can be found for the given target host or no {@link ProxyEngine} can be found for
 * the given protocol, it resets the client stream.</p>
 *
 * <p>This class also provides configuration for the proxy rules.</p>
 */
public class ProxyEngineSelector extends ServerSessionFrameListener.Adapter
{
    protected final Logger LOG = Log.getLogger(getClass());
    private final Map<String, ProxyServerInfo> proxyInfos = new ConcurrentHashMap<>();
    private final Map<String, ProxyEngine> proxyEngines = new ConcurrentHashMap<>();

    @Override
    public final StreamFrameListener onSyn(final Stream clientStream, SynInfo clientSynInfo)
    {
        if (LOG.isDebugEnabled())
            LOG.debug("C -> P {} on {}", clientSynInfo, clientStream);

        final Session clientSession = clientStream.getSession();
        short clientVersion = clientSession.getVersion();
        Fields headers = new Fields(clientSynInfo.getHeaders(), false);

        Fields.Field hostHeader = headers.get(HTTPSPDYHeader.HOST.name(clientVersion));
        if (hostHeader == null)
        {
            if (LOG.isDebugEnabled())
                LOG.debug("No host header found: " + headers);
            rst(clientStream);
            return null;
        }

        String host = hostHeader.getValue();
        int colon = host.indexOf(':');
        if (colon >= 0)
            host = host.substring(0, colon);

        ProxyServerInfo proxyServerInfo = getProxyServerInfo(host);
        if (proxyServerInfo == null)
        {
            if (LOG.isDebugEnabled())
                LOG.debug("No matching ProxyServerInfo found for: " + host);
            rst(clientStream);
            return null;
        }

        String protocol = proxyServerInfo.getProtocol();
        ProxyEngine proxyEngine = proxyEngines.get(protocol);
        if (proxyEngine == null)
        {
            if (LOG.isDebugEnabled())
                LOG.debug("No matching ProxyEngine found for: " + protocol);
            rst(clientStream);
            return null;
        }
        if (LOG.isDebugEnabled())
            LOG.debug("Forwarding request: {} -> {}", clientSynInfo, proxyServerInfo);
        return proxyEngine.proxy(clientStream, clientSynInfo, proxyServerInfo);
    }

    @Override
    public void onPing(Session clientSession, PingResultInfo pingResultInfo)
    {
        // We do not know to which upstream server
        // to send the PING so we just ignore it
    }

    @Override
    public void onGoAway(Session session, GoAwayResultInfo goAwayResultInfo)
    {
        // TODO:
    }

    public Map<String, ProxyEngine> getProxyEngines()
    {
        return new HashMap<>(proxyEngines);
    }

    public void setProxyEngines(Map<String, ProxyEngine> proxyEngines)
    {
        this.proxyEngines.clear();
        this.proxyEngines.putAll(proxyEngines);
    }

    public ProxyEngine getProxyEngine(String protocol)
    {
        return proxyEngines.get(protocol);
    }

    public void putProxyEngine(String protocol, ProxyEngine proxyEngine)
    {
        proxyEngines.put(protocol, proxyEngine);
    }

    public Map<String, ProxyServerInfo> getProxyServerInfos()
    {
        return new HashMap<>(proxyInfos);
    }

    protected ProxyServerInfo getProxyServerInfo(String host)
    {
        return proxyInfos.get(host);
    }

    public void setProxyServerInfos(Map<String, ProxyServerInfo> proxyServerInfos)
    {
        this.proxyInfos.clear();
        this.proxyInfos.putAll(proxyServerInfos);
    }

    public void putProxyServerInfo(String host, ProxyServerInfo proxyServerInfo)
    {
        proxyInfos.put(host, proxyServerInfo);
    }

    private void rst(Stream stream)
    {
        RstInfo rstInfo = new RstInfo(stream.getId(), StreamStatus.REFUSED_STREAM);
        stream.getSession().rst(rstInfo, Callback.Adapter.INSTANCE);
    }

    public static class ProxyServerInfo
    {
        private final String protocol;
        private final String host;
        private final InetSocketAddress address;

        public ProxyServerInfo(String protocol, String host, int port)
        {
            this.protocol = protocol;
            this.host = host;
            this.address = new InetSocketAddress(host, port);
        }

        public String getProtocol()
        {
            return protocol;
        }

        public String getHost()
        {
            return host;
        }

        public InetSocketAddress getAddress()
        {
            return address;
        }

        @Override
        public String toString()
        {
            return "ProxyServerInfo{" +
                    "protocol='" + protocol + '\'' +
                    ", host='" + host + '\'' +
                    ", address=" + address +
                    '}';
        }
    }
}
