/*
 * Copyright (c) 2017 XMLmind Software. All rights reserved. 
 *
 * Author: Hussein Shafie
 *
 * This file is part of the XMLmind W2X project.
 * For conditions of distribution and use, see the accompanying legal.txt file.
 */
package com.xmlmind.w2x_servlet;

import java.io.IOException;
import java.io.File;
import java.io.FileOutputStream;
import javax.servlet.ServletException;
import javax.servlet.ServletConfig;
import com.xmlmind.util.ThrowableUtil;
import com.xmlmind.util.FileUtil;

/*package*/ final class ConfUtil {
    private ConfUtil() {}

    public static String getString(ServletConfig config, 
                                   String key, String defaultValue) 
        throws ServletException {
        String value = config.getInitParameter(key);

        if (value == null || (value = value.trim()).length() == 0) {
            if (defaultValue == null) {
                throw missingParameter(key);
            } else {
                value = defaultValue;
            }
        }

        return value;
    }

    // -----------------------------------------------------------------------

    public static int getInt(ServletConfig config, String key, 
                             String defaultValue, int min, int max) 
        throws ServletException {
        String value = getString(config, key, defaultValue);

        try {
            int num = Integer.parseInt(value);
            if (num >= min && num <= max) {
                return num;
            }
        } catch (NumberFormatException ignored) {}

        throw invalidParameterValue(key, value);
    }

    // -----------------------------------------------------------------------

    /**
     * Option meaning: do not report an error if the file does not exist; 
     * just return it.
     */
    public static final int GET = 0x1;

    /**
     * Option meaning: create file or directory if it does not exist.
     */
    public static final int CREATE = 0x2;

    /**
     * Option meaning: the file must be a directory.
     */
    public static final int DIRECTORY = 0x4;

    /**
     * Option meaning: the file must be writable.
     */
    public static final int WRITABLE = 0x8;

    public static File getFile(ServletConfig config, 
                               String key, String defaultValue,
                               int options, File baseDir) 
        throws ServletException {
        String value = getString(config, key, defaultValue);

        if (value.indexOf('/') >= 0 && File.separatorChar != '/') {
            value = value.replace('/', File.separatorChar);
        }

        File file = new File(value);
        if (!file.isAbsolute() && baseDir != null) {
            file = new File(baseDir, value);
        }

        if (!file.exists()) {
            if ((options & CREATE) != 0) {
                try {
                    if ((options & DIRECTORY) != 0) {
                        FileUtil.checkedMkdirs(file);
                    } else {
                        touch(file);
                    }
                } catch (IOException e) {
                    throw new ServletException(
                        Msg.msg("cannotCreateFileParameter", file, key,
                                ThrowableUtil.reason(e)));
                }
            } else if ((options & GET) != 0) {
                return file;
            }
        }

        if (!file.exists() || 
            !file.canRead() ||
            ((options & DIRECTORY) != 0 && !file.isDirectory()) ||
            ((options & WRITABLE) != 0 && !file.canWrite())) {
            throw invalidParameterValue(key, value);
        }

        return file;
    }

    private static void touch(File file) 
        throws IOException {
        FileOutputStream out = new FileOutputStream(file);
        out.close();
    }

    // -----------------------------------------------------------------------

    public static ServletException missingParameter(String key) {
        return new ServletException(Msg.msg("missingParameter", key));
    }

    public static ServletException invalidParameterValue(String key,
                                                         String value) {
        return new ServletException(Msg.msg("invalidParameter", value, key));
    }

    public static ServletException invalidParameterValue2(String key,
                                                          String value,
                                                          String reason) {
        return new ServletException(Msg.msg("invalidParameter2", value, key,
                                            reason));
    }
}
