/*
 * 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.knox.gateway.services.security.impl;

import org.apache.commons.codec.binary.Base64;
import org.apache.commons.io.FileUtils;
import org.apache.commons.net.ntp.TimeStamp;
import org.apache.knox.gateway.config.GatewayConfig;
import org.apache.knox.gateway.i18n.GatewaySpiMessages;
import org.apache.knox.gateway.i18n.messages.MessagesFactory;
import org.apache.knox.gateway.services.ServiceLifecycleException;
import org.apache.knox.gateway.services.security.EncryptionResult;

import java.io.Console;
import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class CMFMasterService {
  private static final GatewaySpiMessages LOG = MessagesFactory.get( GatewaySpiMessages.class );

  private static final String MASTER_PASSPHRASE = "masterpassphrase";
  private static final String MASTER_PERSISTENCE_TAG = "#1.0# " + TimeStamp.getCurrentTime().toDateString();
  protected char[] master;
  protected String serviceName;
  private ConfigurableEncryptor encryptor = new ConfigurableEncryptor(MASTER_PASSPHRASE);

  public CMFMasterService(String serviceName) {
    super();
    this.serviceName = serviceName;
  }

  public char[] getMasterSecret() {
    return this.master;
  }

  public void setupMasterSecret(String securityDir, String filename,
      boolean persisting, GatewayConfig config)
          throws ServiceLifecycleException {
      encryptor.init(config);
      setupMasterSecret(securityDir, filename, persisting);
  }

  protected void setupMasterSecret(String securityDir, boolean persisting) throws ServiceLifecycleException {
    setupMasterSecret(securityDir, serviceName + "-master", persisting);
  }

  protected void setupMasterSecret(String securityDir, String filename, boolean persisting) throws ServiceLifecycleException {
    File masterFile = new File(securityDir, filename);
    if (masterFile.exists()) {
      try {
        initializeFromMaster(masterFile);
      } catch (Exception e) {
        throw new ServiceLifecycleException("Unable to load the persisted master secret.", e);
      }
    }
    else {
    if (master == null) {
        displayWarning(persisting);
        promptUser();
      }
      if(persisting) {
        persistMaster(master, masterFile);
      }
    }
  }

  protected void promptUser() {
    Console c = System.console();
    if (c == null) {
      LOG.unableToPromptForMasterUseKnoxCLI();
      System.err.println("No console.");
      System.exit(1);
    }

    boolean valid = false;
    do {
        char [] newPassword1 = c.readPassword("Enter master secret: ");
        char [] newPassword2 = c.readPassword("Enter master secret again: ");
        if ( newPassword1.length == 0 ) {
            c.format("Password too short. Try again.%n");
        } else if (!Arrays.equals(newPassword1, newPassword2) ) {
            c.format("Passwords don't match. Try again.%n");
        } else {
            this.master = Arrays.copyOf(newPassword1, newPassword1.length);
            valid = true;
        }
        Arrays.fill(newPassword1, ' ');
        Arrays.fill(newPassword2, ' ');
    } while (!valid);
  }

  protected void displayWarning(boolean persisting) {
    Console c = System.console();
    if (c == null) {
        LOG.unableToPromptForMasterUseKnoxCLI();
        System.err.println("No console.");
        System.exit(1);
    }
    if (persisting) {
      c.printf("***************************************************************************************************\n");
      c.printf("You have indicated that you would like to persist the master secret for this service instance.\n");
      c.printf("Be aware that this is less secure than manually entering the secret on startup.\n");
      c.printf("The persisted file will be encrypted and primarily protected through OS permissions.\n");
      c.printf("***************************************************************************************************\n");
    }
    else {
      c.printf("***************************************************************************************************\n");
      c.printf("Be aware that you will need to enter your master secret for future starts exactly as you do here.\n");
      c.printf("This secret is needed to access protected resources for the service process.\n");
      c.printf("The master secret must be protected, kept secret and not stored in clear text anywhere.\n");
      c.printf("***************************************************************************************************\n");
    }
  }

  protected void persistMaster(char[] master, File masterFile) {
    try {
      EncryptionResult atom = encryptMaster(master);
      ArrayList<String> lines = new ArrayList<>();
      lines.add(MASTER_PERSISTENCE_TAG);

      String line = Base64.encodeBase64String((
          Base64.encodeBase64String(atom.salt) + "::" +
          Base64.encodeBase64String(atom.iv) + "::" +
          Base64.encodeBase64String(atom.cipher)).getBytes(StandardCharsets.UTF_8));
      lines.add(line);
      FileUtils.writeLines(masterFile, StandardCharsets.UTF_8.name(), lines);

      // restrict os permissions to only the user running this process
      chmod("600", masterFile);
    } catch (IOException e) {
      LOG.failedToPersistMasterSecret(e);
    }
  }

  private EncryptionResult encryptMaster(char[] master) throws IOException {
    try {
      return encryptor.encrypt(new String(master));
    } catch (Exception e) {
      LOG.failedToEncryptMasterSecret(e);
      throw new IOException(e);
    }
  }

  protected void initializeFromMaster(File masterFile) throws Exception {
      try {
        List<String> lines = FileUtils.readLines(masterFile, StandardCharsets.UTF_8);
        String tag = lines.get(0);
        LOG.loadingFromPersistentMaster( tag );
        String line = new String(Base64.decodeBase64(lines.get(1)), StandardCharsets.UTF_8);
        String[] parts = line.split("::");
        this.master = new String(encryptor.decrypt(Base64.decodeBase64(parts[0]),
            Base64.decodeBase64(parts[1]), Base64.decodeBase64(parts[2])),
            StandardCharsets.UTF_8).toCharArray();
      } catch (Exception e) {
        LOG.failedToInitializeFromPersistentMaster(masterFile.getName(), e);
        throw e;
      }
  }

  private void chmod(String args, File file) throws IOException {
      // TODO: move to Java 7 NIO support to add windows as well
      // TODO: look into the following for Windows: Runtime.getRuntime().exec("attrib -r myFile");
      if (isUnixEnv()) {
          //args and file should never be null.
          if (args == null || file == null) {
            throw new IllegalArgumentException("nullArg");
          }
          if (!file.exists()) {
            throw new IOException("fileNotFound");
          }

          // " +" regular expression for 1 or more spaces
          final String[] argsString = args.split(" +");
          List<String> cmdList = new ArrayList<>();
          cmdList.add("/bin/chmod");
          cmdList.addAll(Arrays.asList(argsString));
          cmdList.add(file.getAbsolutePath());
          new ProcessBuilder(cmdList).start();
      }
  }

  private boolean isUnixEnv() {
    return (File.separatorChar == '/');
  }
}
