/*
 * 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.cassandra.tools;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;

import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.CommandLineParser;
import org.apache.commons.cli.GnuParser;
import org.apache.commons.cli.HelpFormatter;
import org.apache.commons.cli.Option;
import org.apache.commons.cli.OptionGroup;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.ParseException;
import org.apache.commons.lang3.StringUtils;

import org.apache.cassandra.io.util.File;
import org.mindrot.jbcrypt.BCrypt;

public class HashPassword
{
    private static final String LOGROUNDS_OPTION = "logrounds";
    private static final String HELP_OPTION = "help";
    private static final String ENV_VAR = "environment-var";
    private static final String PLAIN = "plain";
    private static final String INPUT = "input";

    private static final int LOGROUNDS_DEFAULT = 10;
    private static final int MIN_PASS_LENGTH = 4;

    public static void main(String[] args)
    {
        try
        {
            Options options = getOptions();
            CommandLine cmd = parseCommandLine(args, options);

            String password = null;
            if (cmd.hasOption(ENV_VAR))
            {
                password = System.getenv(cmd.getOptionValue(ENV_VAR));
                if (password == null)
                {
                    System.err.println(String.format("Environment variable '%s' is undefined.", cmd.getOptionValue(ENV_VAR)));
                    System.exit(1);
                }
            }
            else if (cmd.hasOption(PLAIN))
            {
                password = cmd.getOptionValue(PLAIN);
            }
            else if (cmd.hasOption(INPUT))
            {
                String input = cmd.getOptionValue(INPUT);
                byte[] fileInput = null;
                if ("-".equals(input))
                {
                    ByteArrayOutputStream os = new ByteArrayOutputStream();
                    int rd;
                    while ((rd = System.in.read()) != -1)
                        os.write(rd);
                    fileInput = os.toByteArray();
                }
                else
                {
                    try
                    {
                        Path file = File.getPath(input);
                        fileInput = Files.readAllBytes(file);
                    }
                    catch (IOException e)
                    {
                        System.err.printf("Failed to read from '%s': %s%n", input, e);
                        System.exit(1);
                    }
                }
                password = new String(fileInput, StandardCharsets.UTF_8);
            }
            else
            {
                System.err.println(String.format("One of the options --%s, --%s or --%s must be used.",
                                                 ENV_VAR, PLAIN, INPUT));
                printUsage(options);
                System.exit(1);
            }

            if (password.chars().anyMatch(i -> i < 32))
                System.err.println("WARNING: The provided plain text password contains non-printable characters (ASCII<32).");

            if (password.length() < MIN_PASS_LENGTH)
                System.err.println("WARNING: The provided password is very short, probably too short to be secure.");

            int logRounds = cmd.hasOption(LOGROUNDS_OPTION) ? Integer.parseInt(cmd.getOptionValue(LOGROUNDS_OPTION)) : LOGROUNDS_DEFAULT;
            if (logRounds < 4 || logRounds > 30)
            {
                System.err.println(String.format("Bad value for --%s %d. " +
                                                 "Please use a value between 4 and 30 inclusively",
                        LOGROUNDS_OPTION, logRounds));
                System.exit(1);
            }

            // The number of rounds is in fact = 2^rounds.
            if (logRounds > 16)
                System.err.println(String.format("WARNING: Using a high number of hash rounds, as configured using '--%s %d' " +
                                                 "will consume a lot of CPU and likely cause timeouts. Note that the parameter defines the " +
                                                 "logarithmic number of rounds: %d becomes 2^%d = %d rounds",
                        LOGROUNDS_OPTION, logRounds,
                        logRounds, logRounds, 1 << logRounds));

            if (password.getBytes().length > 72)
                System.err.println(String.format("WARNING: The provided password has a length of %d bytes, but the underlying hash/crypt algorithm " +
                        "(bcrypt) can only compare up to 72 bytes. The password will be accepted and work, but only compared up to 72 bytes.",
                        password.getBytes().length));

            String hashed = escape(hashpw(password, logRounds));
            System.out.print(hashed);
            System.out.flush();
        }
        catch (Exception e)
        {
            e.printStackTrace();
            System.exit(1);
        }
    }

    private static CommandLine parseCommandLine(String[] args, Options options) throws ParseException
    {
        CommandLineParser parser = new GnuParser();

        CommandLine cmd = parser.parse(options, args, false);

        if (cmd.hasOption(HELP_OPTION))
        {
            printUsage(options);
            System.exit(0);
        }
        return cmd;
    }

    private static Options getOptions()
    {
        Options options = new Options();
        options.addOption("h", HELP_OPTION, false, "Display this help message");
        options.addOption("r", LOGROUNDS_OPTION, true, "Number of hash rounds (default: " + LOGROUNDS_DEFAULT + ").");
        OptionGroup group = new OptionGroup();
        group.addOption(new Option("e", ENV_VAR, true,
                                   "Use value of the specified environment variable as the password"));
        group.addOption(new Option("p", PLAIN, true,
                                   "Argument is the plain text password"));
        group.addOption(new Option("i", INPUT, true,
                                   "Input is a file (or - for stdin) to read the password from. " +
                                   "Make sure that the whole input including newlines is considered. " +
                                   "For example, the shell command 'echo -n foobar | hash_password -i -' will " +
                                   "work as intended and just hash 'foobar'."));
        options.addOptionGroup(group);
        return options;
    }

    private static String hashpw(String password, int rounds)
    {
        return BCrypt.hashpw(password, BCrypt.gensalt(rounds));
    }

    private static String escape(String name)
    {
        return StringUtils.replace(name, "'", "''");
    }

    public static void printUsage(Options options)
    {
        String usage = "hash_password [options]";
        String header = "--\n" +
                        "Hashes a plain text password and prints the hashed password.\n" +
                        "Options are:";
        new HelpFormatter().printHelp(usage, header, options, "");
    }
}
