/*
 *
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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.apache.qpid.server.federation.sasl;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;
import java.security.InvalidKeyException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import java.util.UUID;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import javax.security.sasl.SaslClient;
import javax.security.sasl.SaslException;
import javax.xml.bind.DatatypeConverter;

import org.apache.qpid.server.model.UsernamePasswordCredential;

public abstract class AbstractScramSaslClient implements SaslClient
{

    private static final byte[] INT_1 = new byte[]{0, 0, 0, 1};
    private static final String GS2_HEADER = "n,,";
    private static final Charset ASCII = Charset.forName("ASCII");

    private final String _digestName;
    private final String _hmacName;

    private String _username;
    private final String _clientNonce = UUID.randomUUID().toString();
    private String _serverNonce;
    private byte[] _salt;
    private int _iterationCount;
    private String _clientFirstMessageBare;
    private byte[] _serverSignature;

    enum State
    {
        INITIAL,
        CLIENT_FIRST_SENT,
        CLIENT_PROOF_SENT,
        COMPLETE
    }

    public final String _mechanism;

    private final UsernamePasswordCredential<?> _credentials;

    private State _state = State.INITIAL;

    public AbstractScramSaslClient(final UsernamePasswordCredential credentials,
                                   final String mechanism,
                                   final String digestName,
                                   final String hmacName)
    {
        _mechanism = mechanism;
        _digestName = digestName;
        _hmacName = hmacName;
        _credentials = credentials;

    }

    @Override
    public String getMechanismName()
    {
        return _mechanism;
    }

    @Override
    public boolean hasInitialResponse()
    {
        return true;
    }

    @Override
    public byte[] evaluateChallenge(final byte[] challenge) throws SaslException
    {
        byte[] response;
        switch(_state)
        {
            case INITIAL:
                response = initialResponse();
                _state = State.CLIENT_FIRST_SENT;
                break;
            case CLIENT_FIRST_SENT:
                response = calculateClientProof(challenge);
                _state = State.CLIENT_PROOF_SENT;
                break;
            case CLIENT_PROOF_SENT:
                evaluateOutcome(challenge);
                response = new byte[0];
                _state = State.COMPLETE;
                break;
            default:
                throw new SaslException("No challenge expected in state " + _state);
        }
        return response;
    }

    private void evaluateOutcome(final byte[] challenge) throws SaslException
    {
        String serverFinalMessage = new String(challenge, ASCII);
        String[] parts = serverFinalMessage.split(",");
        if(!parts[0].startsWith("v="))
        {
            throw new SaslException("Server final message did not contain verifier");
        }
        byte[] serverSignature = DatatypeConverter.parseBase64Binary(parts[0].substring(2));
        if(!Arrays.equals(_serverSignature, serverSignature))
        {
            throw new SaslException("Server signature did not match");
        }
    }

    private byte[] calculateClientProof(final byte[] challenge) throws SaslException
    {
        try
        {
            String serverFirstMessage = new String(challenge, ASCII);
            String[] parts = serverFirstMessage.split(",");
            if(parts.length < 3)
            {
                throw new SaslException("Server challenge '" + serverFirstMessage + "' cannot be parsed");
            }
            else if(parts[0].startsWith("m="))
            {
                throw new SaslException("Server requires mandatory extension which is not supported: " + parts[0]);
            }
            else if(!parts[0].startsWith("r="))
            {
                throw new SaslException("Server challenge '" + serverFirstMessage + "' cannot be parsed, cannot find nonce");
            }
            String nonce = parts[0].substring(2);
            if(!nonce.startsWith(_clientNonce))
            {
                throw new SaslException("Server challenge did not use correct client nonce");
            }
            _serverNonce = nonce;
            if(!parts[1].startsWith("s="))
            {
                throw new SaslException("Server challenge '" + serverFirstMessage + "' cannot be parsed, cannot find salt");
            }
            String base64Salt = parts[1].substring(2);
            _salt = DatatypeConverter.parseBase64Binary(base64Salt);
            if(!parts[2].startsWith("i="))
            {
                throw new SaslException("Server challenge '" + serverFirstMessage + "' cannot be parsed, cannot find iteration count");
            }
            String iterCountString = parts[2].substring(2);
            _iterationCount = Integer.parseInt(iterCountString);
            if(_iterationCount <= 0)
            {
                throw new SaslException("Iteration count " + _iterationCount + " is not a positive integer");
            }
            byte[] passwordBytes = saslPrep(_credentials.getPassword()).getBytes("UTF-8");

            byte[] saltedPassword = generateSaltedPassword(passwordBytes);


            String clientFinalMessageWithoutProof =
                    "c=" + DatatypeConverter.printBase64Binary(GS2_HEADER.getBytes(ASCII))
                    + ",r=" + _serverNonce;

            String authMessage = _clientFirstMessageBare + "," + serverFirstMessage + "," + clientFinalMessageWithoutProof;

            byte[] clientKey = computeHmac(saltedPassword, "Client Key");
            byte[] storedKey = MessageDigest.getInstance(_digestName).digest(clientKey);

            byte[] clientSignature = computeHmac(storedKey, authMessage);

            byte[] clientProof = clientKey.clone();
            for(int i = 0 ; i < clientProof.length; i++)
            {
                clientProof[i] ^= clientSignature[i];
            }
            byte[] serverKey = computeHmac(saltedPassword, "Server Key");
            _serverSignature = computeHmac(serverKey, authMessage);

            String finalMessageWithProof = clientFinalMessageWithoutProof
                                           + ",p=" + DatatypeConverter.printBase64Binary(clientProof);
            return finalMessageWithProof.getBytes();
        }
        catch (IllegalArgumentException | NoSuchAlgorithmException | IOException e)
        {
            throw new SaslException(e.getMessage(), e);
        }
    }

    private byte[] computeHmac(final byte[] key, final String string)
            throws SaslException, UnsupportedEncodingException
    {
        Mac mac = createHmac(key);
        mac.update(string.getBytes(ASCII));
        return mac.doFinal();
    }

    private byte[] generateSaltedPassword(final byte[] passwordBytes) throws SaslException
    {
        Mac mac = createHmac(passwordBytes);

        mac.update(_salt);
        mac.update(INT_1);
        byte[] result = mac.doFinal();

        byte[] previous = null;
        for(int i = 1; i < _iterationCount; i++)
        {
            mac.update(previous != null? previous: result);
            previous = mac.doFinal();
            for(int x = 0; x < result.length; x++)
            {
                result[x] ^= previous[x];
            }
        }

        return result;
    }

    private Mac createHmac(final byte[] keyBytes)
            throws SaslException
    {
        try
        {
            SecretKeySpec key = new SecretKeySpec(keyBytes, _hmacName);
            Mac mac = Mac.getInstance(_hmacName);
            mac.init(key);
            return mac;
        }
        catch (NoSuchAlgorithmException e)
        {
            throw new SaslException(e.getMessage(), e);
        }
        catch (InvalidKeyException e)
        {
            throw new SaslException(e.getMessage(), e);
        }
    }


    private byte[] initialResponse() throws SaslException
    {
        try
        {
            StringBuffer buf = new StringBuffer("n=");
            _username = _credentials.getUsername();
            buf.append(saslPrep(_username));
            buf.append(",r=");
            buf.append(_clientNonce);
            _clientFirstMessageBare = buf.toString();
            return (GS2_HEADER + _clientFirstMessageBare).getBytes(ASCII);
        }
        catch (IOException e)
        {
            throw new SaslException(e.getMessage(), e);
        }
    }

    private String saslPrep(String name) throws SaslException
    {
        // TODO - a real implementation of SaslPrep

        if(!ASCII.newEncoder().canEncode(name))
        {
            throw new SaslException("Can only encode names and passwords which are restricted to ASCII characters");
        }

        name = name.replace("=", "=3D");
        name = name.replace(",", "=2C");
        return name;
    }

    @Override
    public boolean isComplete()
    {
        return _state == State.COMPLETE;
    }

    @Override
    public byte[] unwrap(final byte[] incoming, final int offset, final int len) throws SaslException
    {
        throw new IllegalStateException("No security layer supported");
    }

    @Override
    public byte[] wrap(final byte[] outgoing, final int offset, final int len) throws SaslException
    {
        throw new IllegalStateException("No security layer supported");
    }

    @Override
    public Object getNegotiatedProperty(final String propName)
    {
        return null;
    }

    @Override
    public void dispose() throws SaslException
    {

    }

}
