/*
 * $Header: /home/cvspublic/jakarta-slide/proposals/tamino/src/store/org/apache/slide/store/tamino/tools/config/UrmTemplate.java,v 1.1 2004/03/25 16:18:04 juergen Exp $
 * $Revision: 1.1 $
 * $Date: 2004/03/25 16:18:04 $
 *
 * ====================================================================
 *
 * Copyright 1999-2004 The Apache Software Foundation.
 *
 * 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 org.apache.slide.store.tamino.tools.config;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import org.apache.slide.util.Files;
import org.apache.slide.util.JDom;
import org.apache.slide.util.Strings;
import org.apache.slide.util.XAssertionFailed;
import org.apache.slide.util.XException;
import org.apache.slide.util.cli.Abort;
import org.apache.slide.util.cli.Actuals;
import org.apache.slide.util.cli.CommandLine;
import org.apache.slide.util.nodeset.NodeSet;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.xpath.XPath;

public class UrmTemplate {
    public static List listTypes(File catalinaHome) throws Abort, IOException {
        Iterator iter;
        List result;
        String name;
        
        iter = new NodeSet().include("*" + SUFFIX).list(getConf(catalinaHome)).iterator();
        result = new ArrayList();
        while (iter.hasNext()) {
            name = ((File) iter.next()).getName();
            result.add(name.substring(0, name.length() - SUFFIX.length()));
        }
        return result;
    }
    
    private static File getConf(File catalinaHome) throws Abort {
        File conf;
        
        conf = new File(catalinaHome, "conf");
        if (!conf.isDirectory()) {
            throw new Abort("directory not found: " + conf);
        }
        return conf;
    }
        
    private static final String SUFFIX = ".xml.template";
    
    public static UrmTemplate create(File catalinaHome, String type) throws Abort {
        File src;
        File conf;
        Document doc;
        
        conf = getConf(catalinaHome);
        src = new File(conf, type + SUFFIX);
        if (!src.isFile()) {
            throw new Abort("unkown type: " + type);
        }
        try {
            doc = JDom.forFile(src);
        } catch (XException e) {
            throw new XAssertionFailed("invalid template", e);
        }
        
        return new UrmTemplate(doc, getVariables(doc), getDest(catalinaHome));
    }
    
    public static File getDest(File catalinaHome) throws Abort {
        return Files.join(getConf(catalinaHome), "urm_config.xml");
    }
    
    private static List getVariables(Document doc) throws Abort {
        Iterator iter;
        Variable v;
        
        List vars;
        
        vars = new ArrayList();
        try {
            iter = XPath.newInstance("//Attribute").selectNodes(doc).iterator();
        } catch (JDOMException e) {
            throw new XAssertionFailed(e.getMessage());
        }
        while (iter.hasNext()) {
            v = Variable.create((Element) iter.next());
            if (v != null) {
                if (findVariable(vars, v.getName()) != null) {
                    throw new XAssertionFailed("duplicate variable: " + v.getName());
                }
                vars.add(v);
            }
        }
        return vars;
    }
    
    private static Variable findVariable(List vars, String name) {
        Iterator iter;
        Variable v;
        
        iter = vars.iterator();
        while (iter.hasNext()) {
            v = (Variable) iter.next();
            if (name.equals(v.getName())) {
                return v;
            }
        }
        return null;
    }
    
    //--
    
    private final Document doc;
    private final List vars;
    private final File dest;
    
    private UrmTemplate(Document doc, List vars, File dest) {
        this.doc = doc;
        this.vars = vars;
        this.dest = dest;
    }

    public File getDest() {
        return dest;
    }
    public void apply(List arguments) throws Abort, IOException {
        CommandLine cl;
        Actuals actuals;
        Iterator iter;
        Variable v;
        Set names;
        
        cl = commandline(vars);
        actuals = cl.parse(Strings.toArray(arguments));
        iter = vars.iterator();
        while (iter.hasNext()) {
            v = (Variable) iter.next();
            v.set(actuals);
        }
        names = actuals.names();
        if (names.size() != 0) {
            throw new Abort("unkown arguments: " + names);
        }
        JDom.outputter().output(doc, new FileOutputStream(dest));
    }
    
    public String getHelp() {
        Iterator iter;
        Variable v;
        StringBuffer buffer;
        
        buffer = new StringBuffer();
        iter = vars.iterator();
        while (iter.hasNext()) {
            v = (Variable) iter.next();
            buffer.append(v.getHelp());
        }
        return buffer.toString();
    }

    //--
    
    private static CommandLine commandline(List vars) {
        CommandLine cl;
        Iterator iter;
        Variable v;
        
        cl = new CommandLine(false);
        iter = vars.iterator();
        while (iter.hasNext()) {
            v = (Variable) iter.next();
            cl.addOption(v.getName());
        }
        return cl;
    }
}
