/*
 * 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.jboss.test.ws.jaxws.jbws2593;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.util.HashMap;
import java.util.Map;

import org.jboss.arquillian.container.test.api.RunAsClient;
import org.jboss.arquillian.junit5.ArquillianExtension;
import org.jboss.wsf.test.JBossWSTest;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.jboss.wsf.test.JBossWSTestHelper;

/**
 * [JBWS-2593] WSConsume does not generate @XmlJavaTypeAdapter in SEI
 * 
 * http://jira.jboss.org/jira/browse/JBWS-2593
 * 
 * @author alessio.soldano@jboss.com
 * @since 02-Apr-2009
 */
@ExtendWith(ArquillianExtension.class)
public class JBWS2593TestCase extends JBossWSTest
{
   private static final String FS = System.getProperty("file.separator"); // '/' on unix, '\' on windows
   private static final String PS = System.getProperty("path.separator"); // ':' on unix, ';' on windows
   private static final String EXT = ":".equals(PS) ? ".sh" : ".bat";

   private String WSDL_LOCATION_RPC = "jaxws" + FS + "jbws2593" + FS + "wsdl" + FS + "JBWS2593TestRPCService.wsdl";
   
   private String WSDL_LOCATION_DOC = "jaxws" + FS + "jbws2593" + FS + "wsdl" + FS + "JBWS2593TestDOCService.wsdl";

   private String JBOSS_HOME;
   private String TEST_DIR;

   @BeforeEach
   public void setup() throws Exception
   {
      JBOSS_HOME = System.getProperty("jboss.home");
      TEST_DIR = createResourceFile("..").getAbsolutePath();
   }

   @Test
   @RunAsClient
   public void testRPC() throws Exception
   {
      this.internalTest(true);
   }

   @Test
   @RunAsClient
   public void testDOC() throws Exception
   {
      this.internalTest(false);
   }

   private void internalTest(boolean rpc) throws Exception
   {
      // use absolute path for the output to be re-usable
      String absWsdlLoc = getResourceFile(rpc ? WSDL_LOCATION_RPC : WSDL_LOCATION_DOC).getAbsolutePath();
      String absOutput = new File(TEST_DIR, "wsconsume" + FS + "java").getAbsolutePath();
      String command = JBOSS_HOME + FS + "bin" + FS + "wsconsume" + EXT + " -v -k -o " + absOutput + " " + absWsdlLoc;

      // wildfly9 security manager flag changed from -Djava.security.manager to -secmgr.
      // Can't pass -secmgr arg through arquillian because it breaks arquillian's
      // config of our tests.
      // the -secmgr flag MUST be provided as an input arg to jboss-modules so it must
      // come after the jboss-modules.jar ref.
      String additionalJVMArgs = System.getProperty("additionalJvmArgs", "");
      String securityManagerDesignator = additionalJVMArgs.replace("-Djava.security.manager", "-secmgr");

      File policyFile = new File(JBossWSTestHelper.getTestResourcesDir()
          + "/jaxws/jbws2593/jbws2593-security.policy");
      String securityPolicyFile = " -Djava.security.policy=" + policyFile.getCanonicalPath();

      Map<String, String> env = new HashMap<>();
      env.put("JAVA_OPTS", securityManagerDesignator + securityPolicyFile);

      executeCommand(command, null, "wsconsume", env);
      File javaSource = new File(TEST_DIR, "wsconsume" + FS + "java" + FS + "org" + FS + "jbws2593_" + (rpc ? "rpc" : "doc") + FS + "ParameterModeTest.java");
      assertTrue(javaSource.exists(), "Service endpoint interface not generated");
      String contents = readFile(javaSource);
      assertEquals(2, countOccurrences(contents, "@XmlJavaTypeAdapter"));
      assertEquals(2, countOccurrences(contents, "HexBinaryAdapter.class"));
   }

   public static int countOccurrences(String string, String textToSearchFor)
   {
      int count = 0;
      int index = 0;
      while ((index = string.indexOf(textToSearchFor, index)) != -1)
      {
         ++index;
         ++count;
      }
      return count;
   }

   private static String readFile(File file) throws Exception
   {
      BufferedReader input = new BufferedReader(new FileReader(file));
      StringBuilder sb = new StringBuilder();
      try
      {
         String line = null;
         while ((line = input.readLine()) != null)
         {
            sb.append(line);
            sb.append(System.getProperty("line.separator"));
         }
      }
      finally
      {
         input.close();
      }
      return sb.toString();
   }

}
