/*
 * Copyright 2000-2013 JetBrains s.r.o.
 *
 * 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.intellij.cvsSupport2.connections.ssh;

import com.intellij.cvsSupport2.config.ProxySettings;
import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.util.KeyValue;
import com.intellij.openapi.util.Pair;
import com.intellij.util.proxy.CommonProxy;
import com.intellij.util.proxy.NonStaticAuthenticator;
import org.netbeans.lib.cvsclient.connection.ConnectionSettings;

import java.io.IOException;
import java.net.*;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class SocksAuthenticatorManager {

  private final Object myLock;
  private volatile CvsProxySelector mySelector;

  public static SocksAuthenticatorManager getInstance() {
    return ServiceManager.getService(SocksAuthenticatorManager.class);
  }

  private SocksAuthenticatorManager() {
    myLock = new Object();
  }

  public void register(final ConnectionSettings connectionSettings) {
    SshLogger.debug("register in authenticator");
    ensureRegistered();
    mySelector.register(connectionSettings.getHostName(), connectionSettings.getPort(),
                        connectionSettings.getProxyHostName(), connectionSettings.getProxyPort(),
                        connectionSettings.getProxyLogin(), connectionSettings.getProxyPassword());
    CommonProxy.getInstance().setCustomAuth(getClass().getName(), mySelector.getAuthenticator());
  }

  public void unregister(final ConnectionSettings connectionSettings) {
    SshLogger.debug("unregister in authenticator");
    if (!connectionSettings.isUseProxy()) return;
    final int proxyType = connectionSettings.getProxyType();
    if (proxyType != ProxySettings.SOCKS4 && proxyType != ProxySettings.SOCKS5) return;
    mySelector.unregister(connectionSettings.getHostName(), connectionSettings.getPort());
    CommonProxy.getInstance().removeCustomAuth(getClass().getName());
  }

  private void ensureRegistered() {
    // safe double check
    if (mySelector == null) {
      synchronized (myLock) {
        if (mySelector == null) {
          mySelector = new CvsProxySelector();
          CommonProxy.getInstance().setCustom("com.intellij.cvsSupport2.connections.ssh.CvsSocksSelector", mySelector);
        }
      }
    }
  }

  private static class CvsProxySelector extends ProxySelector {
    private final Map<Pair<String, Integer>, Pair<String, Integer>> myKnownHosts;
    private final Map<Pair<String, Integer>, KeyValue<String, String>> myAuthMap;
    private NonStaticAuthenticator myAuthenticator;

    private CvsProxySelector() {
      myKnownHosts = Collections.synchronizedMap(new HashMap<Pair<String, Integer>, Pair<String, Integer>>());
      myAuthMap = Collections.synchronizedMap(new HashMap<Pair<String, Integer>, KeyValue<String, String>>());
      myAuthenticator = new NonStaticAuthenticator() {
        @Override
        public PasswordAuthentication getPasswordAuthentication() {
          final KeyValue<String, String> value = myAuthMap.get(Pair.create(getRequestingHost(), getRequestingPort()));
          if (value != null) {
            return new PasswordAuthentication(value.getKey(), value.getValue().toCharArray());
          }
          return null;
        }
      };
    }

    private NonStaticAuthenticator getAuthenticator() {
      return myAuthenticator;
    }

    public void register(final String host, final int port, final String proxyHost, final int proxyPort, final String login, final String password) {
      final Pair<String, Integer> value = Pair.create(proxyHost, proxyPort);
      myKnownHosts.put(Pair.create(host, port), value);
      myAuthMap.put(value, KeyValue.create(login, password));
    }

    public void unregister(final String host, final int port) {
      final Pair<String, Integer> remove = myKnownHosts.remove(Pair.create(host, port));
      myAuthMap.remove(remove);
    }

    @Override
    public List<Proxy> select(URI uri) {
      final Pair<String, Integer> pair = myKnownHosts.get(Pair.create(uri.getHost(), uri.getPort()));
      if (pair != null) {
        return Collections.singletonList(new Proxy(Proxy.Type.SOCKS, new InetSocketAddress(pair.getFirst(), pair.getSecond())));
      }
      return null;
    }

    @Override
    public void connectFailed(URI uri, SocketAddress sa, IOException ioe) {
    }
  }
}
