/**
 * 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.hcatalog.templeton;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Semaphore;

import org.apache.commons.exec.CommandLine;
import org.apache.commons.exec.DefaultExecutor;
import org.apache.commons.exec.ExecuteException;
import org.apache.commons.exec.ExecuteWatchdog;
import org.apache.commons.exec.PumpStreamHandler;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
 * Execute a local program.  This is a singleton service that will
 * execute programs as non-privileged users on the local box.  See
 * ExecService.run and ExecService.runUnlimited for details.
 */
public class ExecServiceImpl implements ExecService {
    private static final Log LOG = LogFactory.getLog(ExecServiceImpl.class);
    private static AppConfig appConf = Main.getAppConfigInstance();

    private static volatile ExecServiceImpl theSingleton;

    /**
     * Retrieve the singleton.
     */
    public static synchronized ExecServiceImpl getInstance() {
        if (theSingleton == null) {
            theSingleton = new ExecServiceImpl();
        }
        return theSingleton;
    }

    private Semaphore avail;

    private ExecServiceImpl() {
        avail = new Semaphore(appConf.getInt(AppConfig.EXEC_MAX_PROCS_NAME, 16));
    }

    /**
     * Run the program synchronously as the given user. We rate limit
     * the number of processes that can simultaneously created for
     * this instance.
     *
     * @param program   The program to run
     * @param args      Arguments to pass to the program
     * @param env       Any extra environment variables to set
     * @return The result of the run.
     */
    public ExecBean run(String program, List<String> args,
                        Map<String, String> env)
        throws NotAuthorizedException, BusyException, ExecuteException, IOException {
        boolean aquired = false;
        try {
            aquired = avail.tryAcquire();
            if (aquired) {
                return runUnlimited(program, args, env);
            } else {
                throw new BusyException();
            }
        } finally {
            if (aquired) {
                avail.release();
            }
        }
    }

    /**
     * Run the program synchronously as the given user.  Warning:
     * CommandLine will trim the argument strings.
     *
     * @param program   The program to run.
     * @param args      Arguments to pass to the program
     * @param env       Any extra environment variables to set
     * @return The result of the run.
     */
    public ExecBean runUnlimited(String program, List<String> args,
                                 Map<String, String> env)
        throws NotAuthorizedException, ExecuteException, IOException {
        try {
            return auxRun(program, args, env);
        } catch (IOException e) {
            File cwd = new java.io.File(".");
            if (cwd.canRead() && cwd.canWrite())
                throw e;
            else
                throw new IOException("Invalid permissions on Templeton directory: "
                    + cwd.getCanonicalPath());
        }
    }

    private ExecBean auxRun(String program, List<String> args, Map<String, String> env)
        throws NotAuthorizedException, ExecuteException, IOException {
        DefaultExecutor executor = new DefaultExecutor();
        executor.setExitValues(null);

        // Setup stdout and stderr
        int nbytes = appConf.getInt(AppConfig.EXEC_MAX_BYTES_NAME, -1);
        ByteArrayOutputStream outStream = new MaxByteArrayOutputStream(nbytes);
        ByteArrayOutputStream errStream = new MaxByteArrayOutputStream(nbytes);
        executor.setStreamHandler(new PumpStreamHandler(outStream, errStream));

        // Only run for N milliseconds
        int timeout = appConf.getInt(AppConfig.EXEC_TIMEOUT_NAME, 0);
        ExecuteWatchdog watchdog = new ExecuteWatchdog(timeout);
        executor.setWatchdog(watchdog);

        CommandLine cmd = makeCommandLine(program, args);

        LOG.info("Running: " + cmd);
        ExecBean res = new ExecBean();
        res.exitcode = executor.execute(cmd, execEnv(env));
        String enc = appConf.get(AppConfig.EXEC_ENCODING_NAME);
        res.stdout = outStream.toString(enc);
        res.stderr = errStream.toString(enc);

        return res;
    }

    private CommandLine makeCommandLine(String program,
                                        List<String> args)
        throws NotAuthorizedException, IOException {
        String path = validateProgram(program);
        CommandLine cmd = new CommandLine(path);
        if (args != null)
            for (String arg : args)
                cmd.addArgument(arg, false);

        return cmd;
    }

    /**
     * Build the environment used for all exec calls.
     *
     * @return The environment variables.
     */
    public Map<String, String> execEnv(Map<String, String> env) {
        HashMap<String, String> res = new HashMap<String, String>();

        for (String key : appConf.getStrings(AppConfig.EXEC_ENVS_NAME)) {
            String val = System.getenv(key);
            if (val != null) {
                res.put(key, val);
            }
        }
        if (env != null)
            res.putAll(env);
        for (Map.Entry<String, String> envs : res.entrySet()) {
            LOG.info("Env " + envs.getKey() + "=" + envs.getValue());
        }
        return res;
    }

    /**
     * Given a program name, lookup the fully qualified path.  Throws
     * an exception if the program is missing or not authorized.
     *
     * @param path      The path of the program.
     * @return The path of the validated program.
     */
    public String validateProgram(String path)
        throws NotAuthorizedException, IOException {
        File f = new File(path);
        if (f.canExecute()) {
            return f.getCanonicalPath();
        } else {
            throw new NotAuthorizedException("Unable to access program: " + path);
        }
    }
}
