/*
 * 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.jdo.tck.util;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.util.logging.ErrorManager;
import java.util.logging.Filter;
import java.util.logging.Formatter;
import java.util.logging.Handler;
import java.util.logging.Level;
import java.util.logging.LogManager;
import java.util.logging.LogRecord;
import java.util.logging.SimpleFormatter;
import java.util.logging.StreamHandler;

/**
 * A JDK1.4 logging Handler class which delegates to a file handler.
 * Configuration: By default each TCKFileHandler is initialized using 
 * the following LogManager configuration properties:
 * <ul>
 * <li>java.util.logging.TCKFileHandler.level 
 * specifies the default level for the Handler (defaults to Level.ALL).</li>
 * <li>java.util.logging.FileHandler.filter 
 * specifies the name of a Filter class to use (defaults to no Filter).</li>
 * <li>java.util.logging.FileHandler.formatter 
 * specifies the name of a Formatter class to use 
 * (defaults to java.util.logging.SimpleFormatter).</li>
 * <li>java.util.logging.FileHandler.encoding 
 * the name of the character set encoding to use 
 * (defaults to the default platform encoding).</li>
 * <li>java.util.logging.FileHandler.fileName 
 * specifies a the output file name. See below for details.</li>
 * <li>java.util.logging.FileHandler.append 
 * specifies whether the FileHandler should append onto any existing files 
 * (defaults to false).</li>
 * </ul> 
 *  For details on the construction of the file name see method
 *  {@link BatchTestRunner#changeFileName(String)}.
 */
public class TCKFileHandler extends Handler {

    private static final String defaultName = "";
    private static final boolean defaultAppend = false;
    private static final Level defaultLevel = Level.ALL;
    private static final Filter defaultFilter = null;
    private static final Formatter defaultFormatter = new SimpleFormatter();
    private static final String defaultEncoding = null;
    
    private String fileName;
    private boolean append;
    
    private Level level;
    private Filter filter;
    private Formatter formatter;
    private String encoding;
    
    private FileHandlerDelegate delegate;
    
    /**
     * @see Handler#Handler()
     * @throws IOException
     * @throws SecurityException
     */
    public TCKFileHandler() throws IOException, SecurityException {
        configure();
        
        this.delegate = new FileHandlerDelegate();
        
        OutputStream stream = new FileOutputStream(this.fileName, this.append);
        this.delegate.setOutputStream(stream);
        
        this.delegate.setLevel(this.level);
        this.delegate.setFilter(this.filter);
        this.delegate.setFormatter(this.formatter);
        this.delegate.setEncoding(this.encoding);
    }

    /**
     * @see Handler#publish(java.util.logging.LogRecord)
     */
    public synchronized void publish(LogRecord record) {
        this.delegate.publish(record);
    }

    /**
     * @see Handler#close()
     */
    public synchronized void close() throws SecurityException {
        this.delegate.close();
    }

    
    /**
     * @see Handler#flush()
     */
    public void flush() {
        this.delegate.flush();
    }
    
    /**
     * @see Handler#getEncoding()
     */
    public String getEncoding() {
        return this.encoding;
    }

    /**
     * @see Handler#getErrorManager()
     */
    public ErrorManager getErrorManager() {
        return this.delegate.getErrorManager();
    }
    
    /**
     * @see Handler#getFilter()
     */
    public Filter getFilter() {
        return this.filter;
    }
    
    /**
     * @see Handler#getFormatter()
     */
    public Formatter getFormatter() {
        return this.formatter;
    }
    
    /**
     * @see Handler#getLevel()
     */
    public Level getLevel() {
        return this.level;
    }
    
    /**
     * @see Handler#reportError(java.lang.String, java.lang.Exception, int)
     */
    protected void reportError(String msg, Exception ex, int code) {
        this.delegate.reportError(msg, ex, code);
    }
    
    /**
     * @see Handler#setErrorManager(java.util.logging.ErrorManager)
     */
    public void setErrorManager(ErrorManager em) {
        this.delegate.setErrorManager(em);
    }

    /**
     * @see StreamHandler#isLoggable(java.util.logging.LogRecord)
     */
    public boolean isLoggable(LogRecord record) {
        return this.delegate.isLoggable(record);
    }

    /**
     * Sets the file name fileName property.
     * @param fileName The fileName to set
     */
    protected void setPattern(String fileName) {
        this.fileName = BatchTestRunner.changeFileName(fileName);
    }

    /**
     * Sets the append property.
     * @param append The append to set.
     */
    protected void setAppend(boolean append) {
        this.append = append;
    }

    /**
     * Sets the level property.
     * @param level The level to set.
     */
    public void setLevel(Level level) {
        this.level = level;
        if (this.delegate != null) {
            this.delegate.setLevel(level);
        }
    }

    /**
     * Sets the filter property.
     * @param filter The filter to set.
     */
    public void setFilter(Filter filter) {
        this.filter = filter;
        if (this.delegate != null) {
            this.delegate.setFilter(filter);
        }
    }

    /**
     * Sets the formatter property.
     * @param formatter The formatter to set.
     */
    public void setFormatter(Formatter formatter) {
        this.formatter = formatter;
        if (this.delegate != null) {
            this.delegate.setFormatter(formatter);
        }
    }

    /**
     * Sets the encoding property.
     * @param encoding The encoding to set.
     * @throws UnsupportedEncodingException 
     * @throws SecurityException 
     */
    public void setEncoding(String encoding) 
        throws SecurityException, UnsupportedEncodingException {
        this.encoding = encoding;
        if (this.delegate != null) {
            this.delegate.setEncoding(encoding);
        }
    }

    /**
     * Sets the delegate.
     * @param delegate The delegate to set.
     */
    protected void setDelegate(FileHandlerDelegate delegate) {
        this.delegate = delegate;
    }
    
    private void configure() {
        LogManager manager = LogManager.getLogManager();
        String className = this.getClass().getName();
        
        setPattern(getStringProperty(manager, className + ".fileName", defaultName));
        setAppend(getBooleanProperty(manager, className + ".append", defaultAppend));

        setLevel(getLevelProperty(manager, className + ".level", defaultLevel));
        setFilter(getFilterProperty(manager, className + ".filter", defaultFilter));
        setFormatter(getFormatterProperty(manager, className + ".formatter", defaultFormatter));
        try {
            setEncoding(getStringProperty(manager, className + ".encoding", defaultEncoding));
        } catch (Exception e) {
            try {
                setEncoding(defaultEncoding);
            } catch (Exception ex) {
            }
        }
    }
    
    private boolean getBooleanProperty(LogManager manager, String property, 
            boolean defaultValue) {
        boolean result = defaultValue;
        String value = manager.getProperty(property);
        if ( value != null) {
            try {
                result = Boolean.valueOf(value.trim()).booleanValue();
            } catch (Exception ex) {
            }    
        }
        return result;
    }

    private String getStringProperty(LogManager manager, String property, 
            String defaultValue) {
        String result = defaultValue;
        String value = manager.getProperty(property);
        if ( value != null) {
            result = value.trim();
        }
        return result;
    }

    private Level getLevelProperty(LogManager manager, String property, 
            Level defaultValue) {
        Level result = defaultValue;
        String value = manager.getProperty(property);
        if (value != null) {
            try {
                result = Level.parse(value.trim());
            } catch (Exception ex) {
            }
        }
        return result;
    }

    private Filter getFilterProperty(LogManager manager, String property, 
            Filter defaultValue) {
        return (Filter) newInstanceForProperty(manager, property, defaultValue);
    }

    private Formatter getFormatterProperty(LogManager manager, String property, 
            Formatter defaultValue) {
        return (Formatter) newInstanceForProperty(manager, property, defaultValue);
    }

    private Object newInstanceForProperty(LogManager manager, String property, 
            Object defaultValue) {
        Object result = defaultValue;
        String value = manager.getProperty(property);
        if (value != null) {
            try {
                Class clazz = 
                    ClassLoader.getSystemClassLoader().loadClass(value);
                result = clazz.newInstance();
            } catch (Exception ex) {
            }
        }
        return result;
    }
    
    /**
     * This class has been defined to make method 
     * {@link Handler#reportError(java.lang.String, java.lang.Exception, int)}
     * accessible in the outer class. 
     */
    private static class FileHandlerDelegate extends StreamHandler {

        protected void setOutputStream(OutputStream out) {
            super.setOutputStream(out);
        }

        /**
         * @see Handler#reportError(java.lang.String, java.lang.Exception, int)
         */
        protected void reportError(String msg, Exception ex, int code) {
            super.reportError(msg, ex, code);
        }
    }
}
