/**
 * 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);
        }
    }
}
