/*
 * Copyright 2009 Mikhail Kryshen
 *
 * Licensed 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 kryshen.catalina.userconfig;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.regex.Pattern;
import org.apache.juli.logging.LogFactory;

/**
 * Event listener for Host that deploys and updates applications 
 * provided by users listed in passwd database.
 *
 * @author Mikhail Kryshen
 */
public class PasswdUserConfig extends UserConfig {

    private static final String PASSWD_DATABASE = "passwd";

    /* Passwd format details. */
    private static final Pattern PASSWD_SPLIT_PATTERN = Pattern.compile(":");
    private static final int PASSWD_FIELD_USERNAME = 0;
    private static final int PASSWD_FIELD_HOME = 5;

    /**
     * Command for retrieving passwd database.
     */
    private String getent = null;

    /**
     * Path to local passwd file.
     */
    private String passwd = "/etc/passwd";

    
    public PasswdUserConfig() {
        log = LogFactory.getLog(PasswdUserConfig.class);
    }

    /**
     * Get command for retrieving passwd database.
     */
    public String getGetent() {
        return getent;
    }

    /**
     * Set command for retrieving passwd database.
     */
    public void setGetent(String getent) {
        this.getent = getent;
    }

    /**
     * Get path to local passwd file.
     */
    public String getPasswd() {
        return passwd;
    }

    /**
     * Set path to local passwd file.
     */
    public void setPasswd(String passwd) {
        this.passwd = passwd;
    }

    @Override
    protected void deployUserApps() {
        BufferedReader in;

        try {
            if (getent == null) {
                in = new BufferedReader(new FileReader(passwd));
            } else {
                Process process = Runtime.getRuntime().exec(
                       new String[] {getent, PASSWD_DATABASE});

                in = new BufferedReader(
                        new InputStreamReader(process.getInputStream()));
            }

            String line;

            try {
                while ((line = in.readLine()) != null) {
                    String[] fields = PASSWD_SPLIT_PATTERN.split(line);

                    String name = fields[PASSWD_FIELD_USERNAME];
                    File home = new File(fields[PASSWD_FIELD_HOME]);

                    if (!home.isDirectory()) {
                        //log.warn("Invalid home directory for user "
                        //        + name + ": " + home.getPath() + ".");
                        continue;
                    }

                    deployUserApps(name, home);
                }
            } finally {
                in.close();
            }
        } catch (IOException e) {
            log.error("Error reading passwd database.", e);
        } catch (ArrayIndexOutOfBoundsException e) {
            log.error("Invalid passwd format.", e);
        }
    }
}