/*
 * 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.
 */
/*
 * $Id$
 */

package org.apache.xalan.xsltc.compiler;

import java.util.Dictionary;
import java.util.Vector;

import org.apache.bcel.generic.GOTO_W;
import org.apache.bcel.generic.InstructionHandle;
import org.apache.bcel.generic.InstructionList;
import org.apache.xalan.xsltc.compiler.util.ClassGenerator;
import org.apache.xalan.xsltc.compiler.util.MethodGenerator;

/**
 * A test sequence is a sequence of patterns that
 *
 *  (1) occured in templates in the same mode
 *  (2) share the same kernel node type (e.g. A/B and C/C/B)
 *  (3) may also contain patterns matching "*" and "node()"
 *      (element sequence only) or matching "@*" (attribute
 *      sequence only).
 *
 * A test sequence may have a default template, which will be 
 * instantiated if none of the other patterns match. 
 * @author Jacek Ambroziak
 * @author Santiago Pericas-Geertsen
 * @author Erwin Bolwidt <ejb@klomp.org>
 * @author Morten Jorgensen <morten.jorgensen@sun.com>
 */
final class TestSeq {

    /**
     * Integer code for the kernel type of this test sequence
     */
    private int _kernelType;

    /**
     * Vector of all patterns in the test sequence. May include
     * patterns with "*", "@*" or "node()" kernel.
     */
    private Vector _patterns = null;

    /**
     * A reference to the Mode object.
     */
    private Mode _mode = null;

    /**
     * Default template for this test sequence
     */
    private Template _default = null;

    /**
     * Instruction list representing this test sequence.
     */
    private InstructionList _instructionList;

    /**
     * Cached handle to avoid compiling more than once.
     */
    private InstructionHandle _start = null;

    /**
     * Creates a new test sequence given a set of patterns and a mode.
     */
    public TestSeq(Vector patterns, Mode mode) {
	this(patterns, -2, mode);
    }

    public TestSeq(Vector patterns, int kernelType, Mode mode) {
	_patterns = patterns;
	_kernelType = kernelType;
	_mode = mode;
    }

    /**
     * Returns a string representation of this test sequence. Notice
     * that test sequences are mutable, so the value returned by this
     * method is different before and after calling reduce().
     */
    public String toString() {
	final int count = _patterns.size();
	final StringBuffer result = new StringBuffer();

	for (int i = 0; i < count; i++) {
	    final LocationPathPattern pattern =
		(LocationPathPattern) _patterns.elementAt(i);

	    if (i == 0) {
		result.append("Testseq for kernel " + _kernelType)
		      .append('\n');
	    }
	    result.append("   pattern " + i + ": ")
	          .append(pattern.toString())
		  .append('\n');
	}
	return result.toString();
    }

    /**
     * Returns the instruction list for this test sequence
     */
    public InstructionList getInstructionList() {
	return _instructionList;
    }

    /**
     * Return the highest priority for a pattern in this test
     * sequence. This is either the priority of the first or
     * of the default pattern.
     */
    public double getPriority() {
	final Template template = (_patterns.size() == 0) ? _default 
	    : ((Pattern) _patterns.elementAt(0)).getTemplate();
	return template.getPriority();
    }

    /**
     * Returns the position of the highest priority pattern in 
     * this test sequence.
     */
    public int getPosition() {
	final Template template = (_patterns.size() == 0) ? _default 
	    : ((Pattern) _patterns.elementAt(0)).getTemplate();
	return template.getPosition();
    }

    /**
     * Reduce the patterns in this test sequence. Creates a new
     * vector of patterns and sets the default pattern if it
     * finds a patterns that is fully reduced.
     */
    public void reduce() {
	final Vector newPatterns = new Vector();

	final int count = _patterns.size();
	for (int i = 0; i < count; i++) {
	    final LocationPathPattern pattern =
		(LocationPathPattern)_patterns.elementAt(i);
		
	    // Reduce this pattern
	    pattern.reduceKernelPattern();
			
	    // Is this pattern fully reduced?
	    if (pattern.isWildcard()) {
		_default = pattern.getTemplate();
		break; 		// Ignore following patterns 
	    }
	    else {
		newPatterns.addElement(pattern);
	    }
	}
	_patterns = newPatterns;
    }

    /**
     * Returns, by reference, the templates that are included in 
     * this test sequence. Note that a single template can occur 
     * in several test sequences if its pattern is a union.
     */
    public void findTemplates(Dictionary templates) {
	if (_default != null) {
	    templates.put(_default, this);
	}
	for (int i = 0; i < _patterns.size(); i++) {
	    final LocationPathPattern pattern =
		(LocationPathPattern)_patterns.elementAt(i);
	    templates.put(pattern.getTemplate(), this);
	}
    }

    /**
     * Get the instruction handle to a template's code. This is 
     * used when a single template occurs in several test 
     * sequences; that is, if its pattern is a union of patterns 
     * (e.g. match="A/B | A/C").
     */
    private InstructionHandle getTemplateHandle(Template template) {
	return (InstructionHandle)_mode.getTemplateInstructionHandle(template);
    }

    /**
     * Returns pattern n in this test sequence
     */
    private LocationPathPattern getPattern(int n) {
	return (LocationPathPattern)_patterns.elementAt(n);
    }

    /**
     * Compile the code for this test sequence. Compile patterns 
     * from highest to lowest priority. Note that since patterns 
     * can be share by multiple test sequences, instruction lists 
     * must be copied before backpatching.
     */
    public InstructionHandle compile(ClassGenerator classGen,
				     MethodGenerator methodGen,
				     InstructionHandle continuation) 
    {
	// Returned cached value if already compiled
	if (_start != null) {
	    return _start;
	}

	// If not patterns, then return handle for default template
	final int count = _patterns.size();
	if (count == 0) {
	    return (_start = getTemplateHandle(_default));
	}

	// Init handle to jump when all patterns failed
	InstructionHandle fail = (_default == null) ? continuation
	    : getTemplateHandle(_default);
	
	// Compile all patterns in reverse order
	for (int n = count - 1; n >= 0; n--) {
	    final LocationPathPattern pattern = getPattern(n);
	    final Template template = pattern.getTemplate();
	    final InstructionList il = new InstructionList();

	    // Patterns expect current node on top of stack
	    il.append(methodGen.loadCurrentNode());

	    // Apply the test-code compiled for the pattern
	    InstructionList ilist = methodGen.getInstructionList(pattern);
	    if (ilist == null) {
		ilist = pattern.compile(classGen, methodGen);
		methodGen.addInstructionList(pattern, ilist);
	    }

	    // Make a copy of the instruction list for backpatching
	    InstructionList copyOfilist = ilist.copy();

	    FlowList trueList = pattern.getTrueList();
	    if (trueList != null) {
		trueList = trueList.copyAndRedirect(ilist, copyOfilist);
	    }
	    FlowList falseList = pattern.getFalseList();
	    if (falseList != null) {
		falseList = falseList.copyAndRedirect(ilist, copyOfilist);
	    }

	    il.append(copyOfilist);

	    // On success branch to the template code
	    final InstructionHandle gtmpl = getTemplateHandle(template);
	    final InstructionHandle success = il.append(new GOTO_W(gtmpl));

	    if (trueList != null) {
		trueList.backPatch(success);
	    }
	    if (falseList != null) {
		falseList.backPatch(fail);
	    } 

	    // Next pattern's 'fail' target is this pattern's first instruction
	    fail = il.getStart();

	    // Append existing instruction list to the end of this one
	    if (_instructionList != null) {
		il.append(_instructionList);
	    }

	    // Set current instruction list to be this one
	    _instructionList = il;
	}
	return (_start = fail);
    }
}
