/*
 * $Id$
 *
 * 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.struts2.views.java.simple;

import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.conversion.impl.XWorkConverter;
import com.opensymphony.xwork2.inject.Container;
import com.opensymphony.xwork2.util.OgnlTextParser;
import com.opensymphony.xwork2.util.TextParser;
import com.opensymphony.xwork2.util.ValueStack;
import junit.framework.TestCase;
import org.apache.struts2.components.Component;
import org.apache.struts2.components.UIBean;
import org.apache.struts2.components.template.Template;
import org.apache.struts2.components.template.TemplateRenderingContext;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.StringWriter;
import java.util.HashMap;
import java.util.Map;
import java.util.Stack;

import static org.easymock.EasyMock.createMock;
import static org.easymock.EasyMock.createNiceMock;
import static org.easymock.EasyMock.expect;
import static org.easymock.EasyMock.replay;

public abstract class AbstractTest extends TestCase {

    private final Map<String, String> scriptingAttrs = new HashMap<>();
    private final Map<String, String> commonAttrs = new HashMap<>();
    private final Map<String, String> dynamicAttrs = new HashMap<>();

    protected SimpleTheme theme;

    protected StringWriter writer;
    protected Map<String, Object> map;

    protected Template template;
    protected Map<String, Object> stackContext;
    protected ValueStack stack;
    protected TemplateRenderingContext context;
    protected HttpServletRequest request;
    protected HttpServletResponse response;

    protected abstract UIBean getUIBean() throws Exception;

    protected abstract String getTagName();

    @Override
    protected void setUp() throws Exception {
        super.setUp();
        scriptingAttrs.put("onclick", "onclick_");
        scriptingAttrs.put("ondblclick", "ondblclick_");
        scriptingAttrs.put("onmousedown", "onmousedown_");
        scriptingAttrs.put("onmouseup", "onmouseup_");
        scriptingAttrs.put("onmouseover", "onmouseover_");
        scriptingAttrs.put("onmousemove", "onmousemove_");
        scriptingAttrs.put("onmouseout", "onmouseout_");
        scriptingAttrs.put("onfocus", "onfocus_");
        scriptingAttrs.put("onblur", "onblur_");
        scriptingAttrs.put("onkeypress", "onkeypress_");
        scriptingAttrs.put("onkeydown", "onkeydown_");
        scriptingAttrs.put("onkeyup", "onkeyup_");
        scriptingAttrs.put("onselect", "onselect_");
        scriptingAttrs.put("onchange", "onchange_");

        commonAttrs.put("accesskey", "accesskey_");

        dynamicAttrs.put("data-remote", "data-remote_");
        dynamicAttrs.put("data-label", "data-label_");

        theme = new SimpleTheme();
        writer = new StringWriter();
        map = new HashMap<>();

        template = createMock(Template.class);
        stack = createNiceMock(ValueStack.class);
        setUpStack();
        stackContext = new HashMap<>();

        context = new TemplateRenderingContext(template, writer, stack, map, null);
        stackContext.put(Component.COMPONENT_STACK, new Stack<>());
        ActionContext actionContext = ActionContext.of(stackContext).bind();

        request = createNiceMock(HttpServletRequest.class);
        expect(request.getContextPath()).andReturn("/some/path").anyTimes();
        response = createNiceMock(HttpServletResponse.class);

        expect(stack.getActionContext()).andReturn(actionContext).anyTimes();
        expect(stack.getContext()).andReturn(stackContext).anyTimes();

        Container container = createNiceMock(Container.class);
        XWorkConverter converter = new ConverterEx();
        expect(container.getInstance(XWorkConverter.class)).andReturn(converter).anyTimes();
        TextParser parser = new OgnlTextParser();
        expect(container.getInstance(TextParser.class)).andReturn(parser).anyTimes();

        replay(request);
        replay(stack);
        replay(container);

        actionContext.withContainer(container).withServletRequest(request);
    }

    protected static String s(String input) {
        return input.replaceAll("'", "\"");
    }

    protected void expectFind(String expr, Class<?> toClass, Object returnVal) {
        expect(stack.findValue(expr, toClass)).andReturn(returnVal);
        expect(stack.findValue(expr, toClass, false)).andReturn(returnVal);
    }

    protected void expectFind(String expr, Object returnVal) {
        expect(stack.findValue(expr)).andReturn(returnVal).anyTimes();
        expect(stack.findValue(expr, false)).andReturn(returnVal).anyTimes();
    }

    protected void setUpStack() {
        //TODO setup a config with stack and all..for real
    }

    protected void applyScriptingAttrs(UIBean bean) {
        bean.setOnclick(scriptingAttrs.get("onclick"));
        bean.setOndblclick(scriptingAttrs.get("ondblclick"));
        bean.setOnmousedown(scriptingAttrs.get("onmousedown"));
        bean.setOnmouseup(scriptingAttrs.get("onmouseup"));
        bean.setOnmouseover(scriptingAttrs.get("onmouseover"));
        bean.setOnmousemove(scriptingAttrs.get("onmousemove"));
        bean.setOnmouseout(scriptingAttrs.get("onmouseout"));
        bean.setOnfocus(scriptingAttrs.get("onfocus"));
        bean.setOnblur(scriptingAttrs.get("onblur"));
        bean.setOnkeypress(scriptingAttrs.get("onkeypress"));
        bean.setOnkeydown(scriptingAttrs.get("onkeydown"));
        bean.setOnkeyup(scriptingAttrs.get("onkeyup"));
        bean.setOnselect(scriptingAttrs.get("onselect"));
        bean.setOnchange(scriptingAttrs.get("onchange"));
    }

    protected void applyCommonAttrs(UIBean bean) {
        bean.setAccesskey("accesskey_");
    }

    protected void applyDynamicAttrs(UIBean bean) {
        bean.setDynamicAttributes(dynamicAttrs);
    }

    protected void assertScriptingAttrs(String str) {
        for (Map.Entry<String, String> entry : scriptingAttrs.entrySet()) {
            String substr = entry.getKey() + "=\"" + entry.getValue() + "\"";
            assertTrue("String [" + substr + "] was not found in [" + str + "]", str.contains(substr));
        }
    }

    protected void assertCommonAttrs(String str) {
        for (Map.Entry<String, String> entry : commonAttrs.entrySet()) {
            String substr = entry.getKey() + "=\"" + entry.getValue() + "\"";
            assertTrue("String [" + substr + "] was not found in [" + str + "]", str.contains(substr));
        }
    }

    protected void assertDynamicAttrs(String str) {
        for (Map.Entry<String, String> entry : dynamicAttrs.entrySet()) {
            String substr = entry.getKey() + "=\"" + entry.getValue() + "\"";
            assertTrue("String [" + substr + "] was not found in [" + str + "]", str.contains(substr));
        }
    }

    //XWorkConverter doesnt have a public constructor (the one with parameters will require mor config)
    public static class ConverterEx extends XWorkConverter {
        public ConverterEx() {

        }
    }
}
