/*
 * 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.myfaces.extensions.scripting.core.context;

import org.apache.myfaces.extensions.scripting.core.api.ScriptingConst;
import org.apache.myfaces.extensions.scripting.core.api.WeavingContext;
import org.apache.myfaces.extensions.scripting.core.monitor.ClassResource;
import org.apache.myfaces.extensions.scripting.jsf.components.TaintHistory;
import org.apache.myfaces.extensions.scripting.jsf.components.TaintHistoryRenderer;
import org.apache.myfaces.extensions.scripting.core.support.ContextUtils;
import org.apache.myfaces.renderkit.html.HtmlFormRenderer;
import org.apache.myfaces.test.base.AbstractJsfTestCase;
import org.apache.myfaces.test.mock.MockRenderKitFactory;
import org.apache.myfaces.test.mock.MockResponseWriter;
import org.junit.Ignore;

import javax.faces.component.html.HtmlForm;
import javax.servlet.ServletContext;
import java.io.File;
import java.io.StringWriter;

/**
 * @author Werner Punz (latest modification by $Author$)
 * @version $Revision$ $Date$
 *          <p/>
 *          Taint history test, which is the first JSF related test
 *          we try to test here a simple mechanism, the taint history under
 *          JSF Testing conditions.
 */

public class TaintHistoryTest extends AbstractJsfTestCase
{

    ServletContext context;
    private TaintHistory _taintHistory;
    private TaintHistoryRenderer _taintHistoryRenderer;
    private HtmlForm _form;
    private MockResponseWriter _writer;
    private static final String VAL_FILTER = "bla";
    private static final String NO_TAINT_HISTORY_FOUND = "no taint history found";
    private static final String BOOGA_JAVA = "booga.java";
    private static final String TAINT_HISTORY_FOUND = "taint history found";
    private static final String ATTR_NO_ENTRIES = "noEntries";
    private static final String ATTR_FILTER = "filter";

    public TaintHistoryTest()
    {
        super(TaintHistoryTest.class.getName());
    }

    public void setUp() throws Exception
    {
        super.setUp();
        context = ContextUtils.startupSystem();
        _writer = new MockResponseWriter(new StringWriter(), null, null);

        facesContext.setResponseWriter(_writer);
        _taintHistory = new TaintHistory();
        _form = new HtmlForm();
        _taintHistory.setParent(_form);

        facesContext.getViewRoot().setRenderKitId(MockRenderKitFactory.HTML_BASIC_RENDER_KIT);
        facesContext.getRenderKit().addRenderer(
                _taintHistory.getFamily(),
                _taintHistory.getRendererType(),
                new TaintHistoryRenderer());
        facesContext.getRenderKit().addRenderer(
                _form.getFamily(),
                _form.getRendererType(),
                new HtmlFormRenderer());
    }

    @Override
    protected void tearDown() throws Exception
    {
        super.tearDown();
        ContextUtils.stopSystem();
    }

    public void testBooga() {
        assertTrue(true);
    }

    public void testTaintHistory() throws Exception {
            ClassResource historyEntry = new ClassResource();
            historyEntry.setAClass(this.getClass());
            //historyEntry.getRefreshAttribute().requestRefresh();
            //historyEntry.getRefreshAttribute().executedRefresh();
            historyEntry.setScriptingEngine(ScriptingConst.ENGINE_TYPE_JSF_JAVA);
            historyEntry.setFile(new File(BOOGA_JAVA));
           // historyEntry.getRefreshAttribute().requestRefresh();
            //todo set source file
            historyEntry.setTainted(true);

            //WeavingContext.getInstance().addTaintLogEntry(historyEntry);
            //WeavingContext.getRefreshContext().addTaintLogEntry(historyEntry);

            _taintHistory.encodeAll(facesContext);
            facesContext.renderResponse();
            assertFalse(TAINT_HISTORY_FOUND, _writer.getWriter().toString().contains(NO_TAINT_HISTORY_FOUND));

            assertTrue(_writer.getWriter().toString().contains(BOOGA_JAVA));
        }

        public void testSaveRestore() {
            _taintHistory.setFilter(VAL_FILTER);
            _taintHistory.setNoEntries(10);
            Object state = _taintHistory.saveState(facesContext);
            _taintHistory.setFilter("");
            _taintHistory.setNoEntries(0);
            _taintHistory.restoreState(facesContext, state);

            assertTrue(_taintHistory.getFilter().equals(VAL_FILTER));

            assertTrue(_taintHistory.getNoEntries().equals(10));

        }

        public void testNoEntries() throws Exception {
            int noEntries = 10;
            for (int cnt = 0; cnt < 100; cnt++) {
                ClassResource historyEntry = new ClassResource();
                historyEntry.setAClass(this.getClass());
                //historyEntry.getRefreshAttribute().executedRefresh();
                historyEntry.setScriptingEngine(ScriptingConst.ENGINE_TYPE_JSF_JAVA);
                if(cnt < 10)
                    historyEntry.setFile(new File("0"+cnt + "_"+BOOGA_JAVA));
                else
                    historyEntry.setFile(new File(cnt + "_"+BOOGA_JAVA));
                //historyEntry.getRefreshAttribute().requestRefresh();
                //historyEntry.setTaintedOnce(true);
                WeavingContext.getInstance().addTaintLogEntry(historyEntry);
            }

            _taintHistory.setNoEntries(10);
            _taintHistory.encodeAll(facesContext);
            facesContext.renderResponse();

            assertTrue(_writer.getWriter().toString().contains("99_"+BOOGA_JAVA));
            assertFalse(_writer.getWriter().toString().contains("89_"+BOOGA_JAVA));
            assertFalse(_writer.getWriter().toString().contains("00_"+BOOGA_JAVA));
        }

        public void testElAttributes() {
           assertTrue(_taintHistory.getFilter() == null);
           assertTrue(_taintHistory.getNoEntries().equals(TaintHistory.DEFAULT_NO_ENTRIES));
           _taintHistory.setNoEntries(null);

           _taintHistory.getAttributes().put(ATTR_NO_ENTRIES, 20);
           _taintHistory.getAttributes().put(ATTR_FILTER, VAL_FILTER);

           assertTrue(_taintHistory.getNoEntries() == 20);
           assertTrue(_taintHistory.getFilter().equals(VAL_FILTER));
        }


}
