/*
 * Copyright (c) 2007, 2018 Oracle and/or its affiliates. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0, which is available at
 * http://www.eclipse.org/legal/epl-2.0.
 *
 * This Source Code may also be made available under the following Secondary
 * Licenses when the conditions for such availability set forth in the
 * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
 * version 2 with the GNU Classpath Exception, which is available at
 * https://www.gnu.org/software/classpath/license.html.
 *
 * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
 */

/*
 * @(#)Client.java	1.3	03/05/09
 */

package com.sun.ts.tests.jaxws.wsi.j2w.rpc.literal.R4003;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Properties;

import com.sun.javatest.Status;
import com.sun.ts.tests.jaxws.sharedclients.ClientFactory;
import com.sun.ts.tests.jaxws.sharedclients.SOAPClient;
import com.sun.ts.tests.jaxws.sharedclients.rpclitclient.*;
import com.sun.ts.lib.harness.*;

public class Client extends ServiceEETest {
  /**
   * The client.
   */
  private SOAPClient client;

  static J2WRLShared service = null;

  /**
   * Test entry point.
   * 
   * @param args
   *          the command-line arguments.
   */
  public static void main(String[] args) {
    Client test = new Client();
    Status status = test.run(args, System.out, System.err);
    status.exit();
  }

  /**
   * @class.testArgs: -ap jaxws-url-props.dat
   * @class.setup_props: webServerHost; webServerPort; platform.mode;
   *
   * @param args
   * @param properties
   *
   * @throws Fault
   */
  public void setup(String[] args, Properties properties) throws Fault {
    client = ClientFactory.getClient(J2WRLSharedClient.class, properties, this,
        service);
    logMsg("setup ok");
  }

  public void cleanup() {
    logMsg("cleanup");
  }

  /**
   * @testName: testDescriptionEncoding
   *
   * @assertion_ids: WSI:SPEC:R4003
   *
   * @test_Strategy: Retrieve the WSDL, generated by the Java-to-WSDL tool, and
   *                 examine its encoding.
   *
   * @throws Fault
   */
  public void testDescriptionEncoding() throws Fault {
    String descriptionURL = client.getDescriptionURL();
    try {
      URL url = new URL(descriptionURL);
      verifyEncoding(url);
    } catch (MalformedURLException e) {
      throw new Fault(
          "The description URL '" + descriptionURL + "' is invalid (BP-R4003)",
          e);
    }
  }

  protected void verifyEncoding(URL url) throws Fault {
    byte[] bytes = getDescriptionBytes(url);
    int utf;
    String description;
    try {
      description = new String(bytes, "UTF-8");
      utf = 8;
    } catch (Throwable t) {
      try {
        description = new String(bytes, "UTF-16");
        utf = 16;
      } catch (Throwable t2) {
        throw new Fault("Description at '" + url
            + "' cannot be created using neither 'UTF-8' nor 'UTF-16' encoding (BP-R4003)",
            t2);
      }
    }
    if (description.startsWith("<?xml")) {
      int index;
      index = description.indexOf("?>");
      if (index == -1) {
        throw new Fault("Description at '" + url
            + "' has open '<?xml ...' declaration (BP-R4003)");
      }
      String declaration = (description.substring(5, index)).toLowerCase();
      index = declaration.indexOf("encoding");
      if (index != -1) {
        String encoding = (declaration.substring(index + 8)).toLowerCase();
        if (encoding.indexOf("utf-8") != -1) {
          return;
        }
        if (encoding.indexOf("utf-16") != -1) {
          return;
        }
        throw new Fault("Description at '" + url
            + "' is not 'UTF-8','utf-8','utf-16' or 'UTF-16' (BP-R4003)");
      }
    }
  }

  protected byte[] getDescriptionBytes(URL url) throws Fault {
    try {
      InputStream is = url.openStream();
      ByteArrayOutputStream os = new ByteArrayOutputStream();
      byte[] buffer = new byte[1024];
      int length;
      do {
        length = is.read(buffer);
        if (length > 0) {
          os.write(buffer, 0, length);
        }
      } while (length > 0);
      is.close();
      os.flush();
      return os.toByteArray();
    } catch (IOException e) {
      throw new Fault(
          "Unable to read description from '" + url + "' (BP-R4003)", e);
    }
  }
}
