/*
 * Copyright (c) 2013, 2016 Eike Stepper (Loehne, Germany) and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *    Eike Stepper - initial API and implementation
 *    Christian W. Damus (CEA LIST) - Adapted from AuthenticationIndication for 399306
 */
package org.eclipse.emf.cdo.internal.net4j.protocol;

import org.eclipse.emf.cdo.common.protocol.CDOProtocolConstants;
import org.eclipse.emf.cdo.internal.net4j.bundle.OM;

import org.eclipse.net4j.signal.IndicationWithMonitoring;
import org.eclipse.net4j.signal.SignalProtocol;
import org.eclipse.net4j.util.io.ExtendedDataInputStream;
import org.eclipse.net4j.util.io.ExtendedDataOutputStream;
import org.eclipse.net4j.util.om.monitor.OMMonitor;
import org.eclipse.net4j.util.om.monitor.OMMonitor.Async;
import org.eclipse.net4j.util.security.CredentialsUpdateOperation;
import org.eclipse.net4j.util.security.DiffieHellman;
import org.eclipse.net4j.util.security.DiffieHellman.Client.Response;
import org.eclipse.net4j.util.security.DiffieHellman.Server.Challenge;
import org.eclipse.net4j.util.security.IPasswordCredentialsProvider;
import org.eclipse.net4j.util.security.IPasswordCredentialsUpdate;
import org.eclipse.net4j.util.security.IPasswordCredentialsUpdateProvider;
import org.eclipse.net4j.util.security.SecurityUtil;

import org.eclipse.emf.spi.cdo.InternalCDOSession;

import java.io.ByteArrayOutputStream;
import java.util.concurrent.atomic.AtomicReference;

/**
 * Implementation of the CDO client handler for the server-initiated change-credentials protocol.
 *
 * @author Christian W. Damus (CEA LIST)
 */
public class CredentialsChallengeIndication extends IndicationWithMonitoring
{
  private AtomicReference<char[]> newPasswordReceiver;

  private Challenge challenge;

  private CredentialsUpdateOperation operation;

  private String userID;

  public CredentialsChallengeIndication(SignalProtocol<?> protocol)
  {
    super(protocol, CDOProtocolConstants.SIGNAL_CREDENTIALS_CHALLENGE);
    newPasswordReceiver = ChangeCredentialsRequest.NEW_PASSWORD_RECEIVERS.remove(getSession());
  }

  @Override
  public CDOClientProtocol getProtocol()
  {
    return (CDOClientProtocol)super.getProtocol();
  }

  protected InternalCDOSession getSession()
  {
    return (InternalCDOSession)getProtocol().getSession();
  }

  @Override
  protected int getIndicatingWorkPercent()
  {
    return 1;
  }

  @Override
  protected void indicating(ExtendedDataInputStream in, OMMonitor monitor) throws Exception
  {
    operation = in.readEnum(CredentialsUpdateOperation.class);
    userID = in.readString(); // May be null if operation is not reset
    challenge = new Challenge(in);
  }

  @Override
  protected void responding(ExtendedDataOutputStream out, OMMonitor monitor) throws Exception
  {
    monitor.begin();
    Async async = monitor.forkAsync();

    try
    {
      IPasswordCredentialsProvider credentialsProvider = getSession().getCredentialsProvider();
      if (!(credentialsProvider instanceof IPasswordCredentialsUpdateProvider))
      {
        throw new IllegalStateException("No credentials update provider configured"); //$NON-NLS-1$
      }

      IPasswordCredentialsUpdate credentials = ((IPasswordCredentialsUpdateProvider)credentialsProvider).getCredentialsUpdate(userID, operation);
      if (credentials == null)
      {
        // User canceled. Fine
        out.writeBoolean(false);
        return;
      }

      String authUserID = credentials.getUserID();
      String authPassword = SecurityUtil.toString(credentials.getPassword());
      String newPassword = SecurityUtil.toString(credentials.getNewPassword());

      ByteArrayOutputStream baos = new ByteArrayOutputStream();
      ExtendedDataOutputStream stream = new ExtendedDataOutputStream(baos);

      switch (operation)
      {
      case CHANGE_PASSWORD:
        stream.writeString(authUserID);
        stream.writeString(authPassword);
        stream.writeString(newPassword);

        if (newPasswordReceiver != null)
        {
          newPasswordReceiver.set(credentials.getNewPassword());
          newPasswordReceiver = null;
        }

        break;

      case RESET_PASSWORD:
        stream.writeString(authUserID);
        stream.writeString(authPassword);
        stream.writeString(userID);
        stream.writeString(newPassword);
        break;
      }

      stream.close();
      byte[] clearText = baos.toByteArray();

      DiffieHellman.Client client = new DiffieHellman.Client();
      Response response = client.handleChallenge(challenge, clearText);
      out.writeBoolean(true);
      response.write(out);
    }
    catch (Throwable ex)
    {
      out.writeBoolean(false);
      OM.LOG.error(ex);
    }
    finally
    {
      async.stop();
      monitor.done();
    }
  }
}
