/*
 * 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.html5.test;

import java.util.Map;

import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;

import org.apache.myfaces.test.mock.MockResponseWriter;

public class HtmlCheckAttributesUtil
{
    private static void addBaseAttributes(UIComponent component, HtmlRenderedAttr[] attrs)
    {
        Map map = component.getAttributes();
        for(int i = 0; i < attrs.length; i++) 
        {
            HtmlRenderedAttr attr = attrs[i];
            map.put(attr.getName(), attr.getValue());
        }
    }
    
    private static void checkRenderedAttributes(HtmlRenderedAttr[] attrs, String output) throws Exception
    {
        for(int i = 0; i < attrs.length; i++) 
        {
            //assertContainsOnlyOnce(attrs[i], output);
            checkAttributeOccurrences(attrs[i], output);
        }
    }
    
    /**
     * This method adds all attributes from attrs into the component.  After adding the attributes,
     * it calls the encodeAll() method of the component.  The html generated from the component's
     * renderer will be checked to see if the attributes have been rendered correctly.
     * @param component  The component whose attributes will be tested.
     * @param context    
     * @param writer     The ResponseWriter used by the renderer to output the html generated.
     * @param attrs      An array of attributes which will be tested.
     * @throws Exception
     */
    public static void checkRenderedAttributes(
            UIComponent component, 
            FacesContext context, 
            MockResponseWriter writer,
            HtmlRenderedAttr[] attrs) throws Exception 
    {
        
        addBaseAttributes(component, attrs);
        component.encodeBegin(context);
        component.encodeChildren(context);
        component.encodeEnd(context);
        context.renderResponse();
        checkRenderedAttributes(attrs, writer.getWriter().toString());
    }
    
    /**
     * Checks the attrs array if it has elements which were rendered incorrectly.
     * @param attrs The attributes to be checked.
     * @return True if there are attributes not rendered correctly.
     */
    public static boolean hasFailedAttrRender(HtmlRenderedAttr[] attrs) 
    {
        for(int i = 0; i < attrs.length; i++) 
        {
            if(!attrs[i].isRenderSuccessful()) return true;
        }
        return false;
    }
    
    /**
     * Constructs an error message string detailing which attributes were not rendered
     * and which attributes were rendered more than once.
     * @param attrs   The attributes to be tested.
     * @param actual  The html generated by the renderer.
     * @return The error message.
     */
    public static String constructErrorMessage(HtmlRenderedAttr[] attrs, String actual) 
    {
        StringBuffer messgBuffer = new StringBuffer();
        for(int i = 0; i < attrs.length; i++) 
        {
            if(attrs[i].getErrorCode() == HtmlRenderedAttr.RENDERED_MORE_TIMES_THAN_EXPECTED) 
            {
                messgBuffer.append(attrs[i].getName()).append(" (");
                messgBuffer.append(attrs[i].getExpectedHtml()).append(") was rendered more times (");
                messgBuffer.append(attrs[i].getActualOccurrences()).append(") than expected (");
                messgBuffer.append(attrs[i].getExpectedOccurrences()).append(").");
                messgBuffer.append(System.getProperty("line.separator"));
            } 
            else if(attrs[i].getErrorCode() == HtmlRenderedAttr.RENDERED_LESS_TIMES_THAN_EXPECTED)
            {
                messgBuffer.append(attrs[i].getName()).append(" (");
                messgBuffer.append(attrs[i].getExpectedHtml()).append(") was rendered less times (");
                messgBuffer.append(attrs[i].getActualOccurrences()).append(") than expected (");
                messgBuffer.append(attrs[i].getExpectedOccurrences()).append(").");
                messgBuffer.append(System.getProperty("line.separator"));
            }
        }
        messgBuffer.append("Actual HTML: ").append(actual);
        return messgBuffer.toString();
    }
    
    private static void checkAttributeOccurrences(HtmlRenderedAttr attr, String actual)
    {
        String expectedHtml = attr.getExpectedHtml();
        
        int index;
        int offset = 0;
        while((index=actual.indexOf(expectedHtml,offset)) != -1) 
        {
            attr.increaseActualOccurrences();
            if(attr.getActualOccurrences() > attr.getExpectedOccurrences()) 
            {
                attr.setErrorCode(HtmlRenderedAttr.RENDERED_MORE_TIMES_THAN_EXPECTED);
                return;
            } 

            offset += index + expectedHtml.length();
        }
        
        if(attr.getActualOccurrences() < attr.getExpectedOccurrences()) 
        {
            attr.setErrorCode(HtmlRenderedAttr.RENDERED_LESS_TIMES_THAN_EXPECTED);
        } 
        else 
        {
            attr.setRenderSuccessful(true);
        }
    }

}
