/*
 * JBoss, Home of Professional Open Source.
 * Copyright 2010, Red Hat Middleware LLC, and individual contributors
 * as indicated by the @author tags. See the copyright.txt file in the
 * distribution for a full listing of individual contributors.
 *
 * This is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; either version 2.1 of
 * the License, or (at your option) any later version.
 *
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this software; if not, write to the Free
 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
 */
package org.jboss.test.ws.jaxws.jbws3041.service;

import java.util.List;

import javax.xml.soap.SOAPMessage;
import javax.xml.ws.handler.MessageContext;
import javax.xml.ws.handler.soap.SOAPMessageContext;

import org.jboss.test.ws.jaxws.common.Handler_Util;
import org.jboss.test.ws.jaxws.common.JAXWS_Util;
import org.jboss.wsf.common.DOMUtils;
import org.jboss.wsf.common.handler.GenericSOAPHandler;
import org.w3c.dom.Element;

@SuppressWarnings("unchecked")
public class ServerSOAPHandler extends GenericSOAPHandler
{

   public boolean handleInbound(MessageContext context)
   {
      SOAPMessage msg = ((SOAPMessageContext) context).getMessage();
      JAXWS_Util.dumpSOAPMessage(msg, true);
      JAXWS_Util.dumpSOAPMessage(msg, false);

      if (Handler_Util.checkForMsg(context, "GetEPRAndVerifyMetaDataAndRefParamsTest1")
            || Handler_Util.checkForMsg(context, "GetPortAndVerifyRefParamsAreSentTest1")
            || Handler_Util.checkForMsg(context, "GetPortAndVerifyRefParamsAreSentTest2")
            || Handler_Util.checkForMsg(context, "GetPortAndVerifyModifiedRefParamsAreSentTest3"))
      {
         List<Element> rp = (List<Element>) context.get(MessageContext.REFERENCE_PARAMETERS);
         boolean result1 = false;
         boolean result2 = false;
         if (Handler_Util.checkForMsg(context, "GetPortAndVerifyModifiedRefParamsAreSentTest3"))
         {
            result1 = assertReferenceParameter(rp, "MyParam1", "MyValue1");
            result2 = assertReferenceParameter(rp, "MyParam2", "MyValue2");
         }
         else
         {
            result1 = assertReferenceParameter(rp, "MyParam1", "Hello");
            result2 = assertReferenceParameter(rp, "MyParam2", "There");
         }

         if ((!result1) && (!result2))
         {
            throw new RuntimeException(
                  "Reference Parameter MyParam1 and MyParam2 were either not found or their values were wrong");
         }
         else if (!result1)
         {
            throw new RuntimeException("Reference Parameter MyParam1 was not found or it's value was wrong");
         }
         else if (!result2)
         {
            throw new RuntimeException("Reference Parameter MyParam2 was not found or it's value was wrong");
         }
      }

      return true;
   }

   private boolean assertReferenceParameter(final List<Element> refParams, final String paramName,
         final String expectedValue)
   {
      System.out.println("Searching for Reference Parameter '" + paramName + "' with value '" + expectedValue + "'");

      for (int i = 0; i < refParams.size(); i++)
      {
         final Element paramElement = (Element) refParams.get(i);
         boolean found = this.assertReferenceParameterValue(paramElement, paramName, expectedValue);
         if (found)
         {
            System.out.println("Found Reference Parameter '" + paramName + "' with value '" + expectedValue + "'");
            return true;
         }
      }

      return false;
   }

   private boolean assertReferenceParameterValue(final Element paramElement, final String refParamName,
         final String expectedValue)
   {
      if (!paramElement.getLocalName().equals(refParamName))
         return false;

      final String actualValue = DOMUtils.getTextContent(paramElement);

      return expectedValue.equals(actualValue);
   }
}
