package com.bitmechanic.maxq.generator;

import com.bitmechanic.maxq.Test;
import com.bitmechanic.maxq.Utils;
import com.bitmechanic.maxq.HttpTestCase;
import com.bitmechanic.maxq.IScriptAdapter;
import com.bitmechanic.maxq.Param;

import java.util.Properties;
import java.util.HashSet;
import java.io.File;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;


/**
 * Generates a test case in Twill script.
 * Take a look at the IScriptGenerator Interface to see how to specify which one you want.
 * The important information is that this class generates a Twill script.
 * @see IScriptGenerator
 * @author Titus Brown titus@caltech.edu
 */

public class TwillScriptGenerator extends AbstractCodeGenerator {
    private HashSet paramsSet = new HashSet();
    private boolean ignorePage = false;

    private static final Log log = LogFactory.getLog(TwillScriptGenerator.class);

    public TwillScriptGenerator(IScriptAdapter adapter) {
        super(adapter, new String[]{"^# testname\\s+(\\w+)"});
    }

    public static String getGeneratorDescription() {
        return "twill script";
    }
    
    public void doNew() {
        String s =
            "# Generated by MaxQ ["+getClass().getName()+"]"+EOL+
	    "# testname test" + EOL + 
            EOL;

        s = s +
            EOL+
            "    # ^^^ Insert new recordings here.  (Do not remove this line.)"+EOL;


        getScriptAdapter().append(s);
    }

    public void doParameterList(Param[] params) throws Utils.UserException {
        int i;
        for (i = 0; i < params.length; i ++) {
	    String value = params[i].value;
	    String flag = "";

	    if (paramsSet.contains(params[i].name)) {
		flag = "+";
	    } else {
		paramsSet.add(params[i].name);
	    }

	    value = Utils.replace(value, "\\", "\\\\");
	    value = Utils.replace(value, "'", "\\'");
	    value = Utils.replace(value, "\"", "\\\"");
	    String s = "fv 1 " + params[i].name + " " + flag + "\"" +
		value + "\"";
            insertStmt(s);
        }
    }

    public void doCallUrl(String url, String method, String data, String contentLength) throws Utils.UserException {

	if (!paramsSet.isEmpty()) {
	    insertStmt("submit");
	} else {
	    int loc = url.indexOf("favicon.ico");
	    if (loc != -1 && loc == url.length() - 11) {
		ignorePage = true;
	    }

	    if (!ignorePage) {
		insertStmt("go " + url);
	    }
	}

	paramsSet = new HashSet();
    }

    public void doSetData(String data) throws Utils.UserException {
	/*
        insertStmt("data = '" + data + "'");
	*/
    }

    public void doAssertResponse(String respCode) throws Utils.UserException {
	if (!ignorePage) {
	    int code = Integer.decode(respCode).intValue();
	    if (code != 301 && code != 302) {
		insertStmt("code " + respCode);
	    }
	}
    }

    public void doTidyCode(String url) throws Utils.UserException {
    }

    public void doResponseForStdOut(String url) throws Utils.UserException {
    }

    public void doResponseForFile() throws Utils.UserException {
    }

    public void doTestUrlMessage(String url) throws Utils.UserException {
    }

    public String[] getValidFileExtensions() {
        return new String[] {".twill", ".txt"};
    }

    public void doStartRecording() {
    }

    public void doStopRecording() {
    }

    /**
     * Appends an EOL char to scriptAdapter
     */
    public void doEndTransaction() throws Utils.UserException {
        // Add a newline for readability.
	if (!ignorePage) {
	    insertStmt("");
	}

	ignorePage = false;
    }

    /**
     * Inserts a string into the script, with a newline appended.
     */
    private void insertStmt(String s) throws Utils.UserException {
        insert(s + EOL);
    }
}
