/*
 * 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.jackrabbit.oak.plugins.blob.datastore.directaccess;

import java.nio.charset.StandardCharsets;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.time.Instant;
import java.util.Optional;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;

import com.google.common.base.Joiner;

import org.apache.commons.codec.binary.Base64;
import org.apache.jackrabbit.oak.spi.blob.AbstractSharedBackend;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Represents an upload token returned by
 * {@link DataRecordAccessProvider#initiateDataRecordUpload(long, int)} and
 * used in subsequent calls to {@link
 * DataRecordAccessProvider#completeDataRecordUpload(String)}.  This class
 * handles creation, signing, and parsing of the token and uses a provided
 * secret key to sign the contents of the token and to validate contents of
 * tokens.
 */
public class DataRecordUploadToken {
    private static Logger LOG = LoggerFactory.getLogger(DataRecordUploadToken.class);

    private String blobId;
    private Optional<String> uploadId;

    /**
     * Create an upload token from the provided {@code blobId} and {@code
     * uploadId}.  At creation time the token is not encoded or signed; to do
     * that call {@link #getEncodedToken(byte[])} after creating the token.
     *
     * @param blobId The blob ID, usually a {@link
     *        org.apache.jackrabbit.core.data.DataIdentifier}.
     * @param uploadId A free-form string used to identify this upload.  This
     *        may be provided by the service provider; if not a free-form
     *        upload ID generated by the implementation will suffice.  May be
     *        {@code null} if no upload ID is available.  However, some service
     *        providers will require an upload ID to complete the upload so be
     *        sure to check whether the service provider API provides one and
     *        use that if it is available.
     */
    public DataRecordUploadToken(@NotNull String blobId, @Nullable String uploadId) {
        this.blobId = blobId;
        this.uploadId = Optional.ofNullable(uploadId);
    }

    /**
     * Create an upload token instance from the provided encoded token string,
     * using the provided secret key to verify the string.  The encoded token
     * string should have been created originally by a prior call to {@link
     * #getEncodedToken(byte[])}.
     * <p>
     * This method will parse and validate the contents of the provided encoded
     * token string.  An instance of this class is returned if the parsing and
     * validation is successful.
     * <p>
     * A secret key is required to verify the encoded token.  You are strongly
     * encouraged to use the secret key used by the data store backend
     * implementation.  This key can be obtained by calling {@link
     * AbstractSharedBackend#getOrCreateReferenceKey()}.
     *
     * @param encoded The encoded, signed token string.
     * @param secret The secret key to be used to verify the contents of the
     *         token string.
     * @return A new instance containing the parsed upload token propreties.
     * @throws IllegalArgumentException if the token string cannot be parsed or
     *         if validation fails.
     */
    public static DataRecordUploadToken fromEncodedToken(@NotNull String encoded, @NotNull byte[] secret)
            throws IllegalArgumentException {
        final String[] parts = encoded.split("#", 2);
        if (parts.length < 2) {
            throw new IllegalArgumentException("Invalid upload token");
        }

        final String toBeDecoded = parts[0];
        final String expectedSig = parts[1];
        final String actualSig = getSignedString(toBeDecoded, secret);
        if (!expectedSig.equals(actualSig)) {
            throw new IllegalArgumentException("Invalid upload token");
        }

        String decoded = decodeBase64(toBeDecoded);
        String decodedParts[] = decoded.split("#");
        if (decodedParts.length < 2) {
            throw new IllegalArgumentException("Invalid upload token");
        }

        return new DataRecordUploadToken(decodedParts[0], decodedParts.length > 2 ? decodedParts[2] : null);
    }

    /**
     * Generate an encoded, signed token string from this instance.  The
     * resulting token can later be parsed and validated by {@link
     * #fromEncodedToken(String, byte[])}.
     * <p>
     * A secret key is required to generate the encoded token.  You are strongly
     * encouraged to use the secret key used by the data store backend
     * implementation.  This key can be obtained by calling {@link
     * AbstractSharedBackend#getOrCreateReferenceKey()}.
     *
     * @param secret The secret key used to sign the contents of the token.
     * @return An encoded token string that can later be used to uniquely and
     *         securely identify an upload.
     */
    public String getEncodedToken(@NotNull byte[] secret) {
        String now = Instant.now().toString();
        String toBeEncoded = uploadId.isPresent() ?
                Joiner.on("#").join(blobId, now, uploadId.get()) :
                Joiner.on("#").join(blobId, now);
        String toBeSigned = encodeBase64(toBeEncoded);

        String sig = getSignedString(toBeSigned, secret);
        return sig != null ? Joiner.on("#").join(toBeSigned, sig) : toBeSigned;
    }

    /** Returns the base64 encoded HMAC signature */
    private static String getSignedString(String toBeSigned, byte[] secret) {
        try {
            final String algorithm = "HmacSHA1";
            Mac mac = Mac.getInstance(algorithm);
            mac.init(new SecretKeySpec(secret, algorithm));
            byte[] hash = mac.doFinal(toBeSigned.getBytes(StandardCharsets.UTF_8));
            return encodeBase64(hash);
        }
        catch (NoSuchAlgorithmException | InvalidKeyException e) {
            LOG.warn("Could not sign upload token", e);
        }
        return null;
    }

    private static String encodeBase64(String string) {
        return Base64.encodeBase64String(string.getBytes(StandardCharsets.UTF_8));
    }

    private static String encodeBase64(byte[] bytes) {
        return Base64.encodeBase64String(bytes);
    }

    private static String decodeBase64(String encodedString) {
        return new String(Base64.decodeBase64(encodedString), StandardCharsets.UTF_8);
    }

    /**
     * Returns the blob ID of this instance.
     *
     * @return The blob ID.
     */
    public String getBlobId() {
        return blobId;
    }

    /**
     * Returns the upload ID of this instance.
     *
     * @return The upload ID.
     */
    public Optional<String> getUploadId() {
        return uploadId;
    }
}
