/*
 * 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.nifi.processors.standard.util;

import org.apache.commons.lang3.StringUtils;
import org.apache.nifi.processors.standard.EncryptContent;
import org.bouncycastle.bcpg.ArmoredOutputStream;
import org.bouncycastle.openpgp.PGPCompressedData;
import org.bouncycastle.openpgp.PGPCompressedDataGenerator;
import org.bouncycastle.openpgp.PGPEncryptedData;
import org.bouncycastle.openpgp.PGPEncryptedDataGenerator;
import org.bouncycastle.openpgp.PGPException;
import org.bouncycastle.openpgp.PGPLiteralData;
import org.bouncycastle.openpgp.PGPLiteralDataGenerator;
import org.bouncycastle.openpgp.operator.PGPKeyEncryptionMethodGenerator;
import org.bouncycastle.openpgp.operator.jcajce.JcePGPDataEncryptorBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.security.SecureRandom;
import java.util.Date;
import java.util.zip.Deflater;

/**
 * This class contains static utility methods to assist with common PGP operations.
 */
public class PGPUtil {
    private static final Logger logger = LoggerFactory.getLogger(PGPUtil.class);

    public static final int BUFFER_SIZE = 65536;
    public static final int BLOCK_SIZE = 4096;

    public static void encrypt(InputStream in, OutputStream out, String algorithm, String provider, int cipher, String filename, PGPKeyEncryptionMethodGenerator encryptionMethodGenerator) throws
            IOException, PGPException {
        if (StringUtils.isEmpty(algorithm)) {
            throw new IllegalArgumentException("The algorithm must be specified");
        }
        final boolean isArmored = EncryptContent.isPGPArmoredAlgorithm(algorithm);
        OutputStream output = out;
        if (isArmored) {
            output = new ArmoredOutputStream(out);
        }

        // Default value, do not allow null encryption
        if (cipher == PGPEncryptedData.NULL) {
            logger.warn("Null encryption not allowed; defaulting to AES-128");
            cipher = PGPEncryptedData.AES_128;
        }

        try {
            // TODO: Can probably hard-code provider to BC and remove one method parameter
            PGPEncryptedDataGenerator encryptedDataGenerator = new PGPEncryptedDataGenerator(
                    new JcePGPDataEncryptorBuilder(cipher).setWithIntegrityPacket(true).setSecureRandom(new SecureRandom()).setProvider(provider));

            encryptedDataGenerator.addMethod(encryptionMethodGenerator);

            try (OutputStream encryptedOut = encryptedDataGenerator.open(output, new byte[BUFFER_SIZE])) {
                PGPCompressedDataGenerator compressedDataGenerator = new PGPCompressedDataGenerator(PGPCompressedData.ZIP, Deflater.BEST_SPEED);
                try (OutputStream compressedOut = compressedDataGenerator.open(encryptedOut, new byte[BUFFER_SIZE])) {
                    PGPLiteralDataGenerator literalDataGenerator = new PGPLiteralDataGenerator();
                    try (OutputStream literalOut = literalDataGenerator.open(compressedOut, PGPLiteralData.BINARY, filename, new Date(), new byte[BUFFER_SIZE])) {

                        final byte[] buffer = new byte[BLOCK_SIZE];
                        int len;
                        while ((len = in.read(buffer)) > -1) {
                            literalOut.write(buffer, 0, len);
                        }
                    }
                }
            }
        } finally {
            if (isArmored) {
                output.close();
            }
        }
    }
}
