/*
 * 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.
 */

#include "adb_test_framework.h"

/**
 * AXIS2C-1658 Test: WSDL Fault Definition Validation
 *
 * Issue: https://issues.apache.org/jira/browse/AXIS2C-1658
 * Problem: Error parsing WSDL - "Part 'DatiFondiFault' of fault message must be defined with 'element=QName' and not 'type=QName'"
 *
 * Root Cause Analysis (2024-11-21):
 * - This is NOT a code generation bug but a WSDL specification compliance issue
 * - User's WSDL incorrectly defines fault message with type= instead of element=
 * - WSDL standard requires fault messages to use element= regardless of binding style
 * - Issue affects WSDL2Java, need to verify if native WSDL2C has same validation
 *
 * WSDL Standards:
 * - Document/Literal: requires element= for all message parts
 * - RPC/Encoded: can use type= for regular message parts
 * - Fault messages: MUST always use element= (even in RPC style)
 *
 * Classification:
 * - User Error: Invalid WSDL definition
 * - Documentation Issue: Need clearer guidance
 * - Validation Enhancement: Better error messages needed
 */

/* Test AXIS2C-1658 case - verify fault message validation behavior */
adb_test_result_t test_axis2c_1658_invalid_fault_definition(void) {
    printf("Testing AXIS2C-1658: WSDL fault definition validation (type vs element)...\n");

    adb_codegen_test_t test_config = {
        .wsdl_path = "wsdl/axis2c_1658_invalid_fault_test.wsdl",
        .output_dir = "output/axis2c_1658_invalid_fault_test",
        .databinding = "adb",
        .unwrap = 1,
        .server_side = 1
    };

    /* Create a WSDL with the same problematic pattern from AXIS2C-1658 */
    const char *invalid_fault_wsdl =
        "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
        "<wsdl:definitions xmlns:apachesoap=\"http://xml.apache.org/xml-soap\"\n"
        "                  xmlns:impl=\"http://es.ubi.it/srv/datifondi\"\n"
        "                  xmlns:intf=\"http://es.ubi.it/srv/datifondi\"\n"
        "                  xmlns:tns1=\"http://es.ubi.it/typ/cm\"\n"
        "                  xmlns:tns2=\"it.objectway.owfs.external.data.impl\"\n"
        "                  xmlns:wsdl=\"http://schemas.xmlsoap.org/wsdl/\"\n"
        "                  xmlns:wsdlsoap=\"http://schemas.xmlsoap.org/wsdl/soap/\"\n"
        "                  xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n"
        "                  targetNamespace=\"http://es.ubi.it/srv/datifondi\">\n"
        "  <wsdl:types>\n"
        "    <schema targetNamespace=\"http://es.ubi.it/typ/cm\" xmlns=\"http://www.w3.org/2001/XMLSchema\">\n"
        "      <import namespace=\"http://es.ubi.it/srv/datifondi\"/>\n"
        "      <import namespace=\"it.objectway.owfs.external.data.impl\"/>\n"
        "      \n"
        "      <complexType name=\"Contesto\">\n"
        "        <sequence>\n"
        "          <element name=\"guid\" type=\"xsd:string\"/>\n"
        "          <element name=\"token\" nillable=\"true\" type=\"xsd:string\"/>\n"
        "          <element name=\"abi\" type=\"xsd:integer\"/>\n"
        "          <element name=\"codRichiedente\" type=\"xsd:string\"/>\n"
        "        </sequence>\n"
        "      </complexType>\n"
        "      \n"
        "      <complexType name=\"BustaIN\">\n"
        "        <sequence>\n"
        "          <element name=\"contesto\" type=\"tns1:Contesto\"/>\n"
        "        </sequence>\n"
        "      </complexType>\n"
        "      \n"
        "      <complexType name=\"Esito\">\n"
        "        <sequence>\n"
        "          <element name=\"esito\" nillable=\"true\" type=\"xsd:boolean\"/>\n"
        "          <element name=\"codice\" nillable=\"true\" type=\"xsd:string\"/>\n"
        "          <element name=\"messaggio\" nillable=\"true\" type=\"xsd:string\"/>\n"
        "        </sequence>\n"
        "      </complexType>\n"
        "      \n"
        "      <complexType name=\"BustaOUT\">\n"
        "        <sequence>\n"
        "          <element name=\"esito\" type=\"tns1:Esito\"/>\n"
        "        </sequence>\n"
        "      </complexType>\n"
        "      \n"
        "      <complexType name=\"Errore\">\n"
        "        <sequence>\n"
        "          <element name=\"id\" nillable=\"true\" type=\"xsd:string\"/>\n"
        "          <element name=\"tipo\" nillable=\"true\" type=\"xsd:string\"/>\n"
        "          <element name=\"messaggio\" nillable=\"true\" type=\"xsd:string\"/>\n"
        "          <element name=\"guid\" nillable=\"true\" type=\"xsd:string\"/>\n"
        "        </sequence>\n"
        "      </complexType>\n"
        "    </schema>\n"
        "    \n"
        "    <schema targetNamespace=\"http://es.ubi.it/srv/datifondi\" xmlns=\"http://www.w3.org/2001/XMLSchema\">\n"
        "      <import namespace=\"it.objectway.owfs.external.data.impl\"/>\n"
        "      <import namespace=\"http://es.ubi.it/typ/cm\"/>\n"
        "      \n"
        "      <complexType name=\"BINDatiFondi\">\n"
        "        <complexContent>\n"
        "          <extension base=\"tns1:BustaIN\">\n"
        "            <sequence>\n"
        "              <element name=\"inputDatiFondi\" type=\"xsd:string\"/>\n"
        "            </sequence>\n"
        "          </extension>\n"
        "        </complexContent>\n"
        "      </complexType>\n"
        "      \n"
        "      <complexType name=\"BOUDatiFondi\">\n"
        "        <complexContent>\n"
        "          <extension base=\"tns1:BustaOUT\">\n"
        "            <sequence>\n"
        "              <element name=\"outputDatiFondi\" type=\"tns2:listaPosizioni\"/>\n"
        "            </sequence>\n"
        "          </extension>\n"
        "        </complexContent>\n"
        "      </complexType>\n"
        "      \n"
        "      <!-- The problematic fault type from AXIS2C-1658 -->\n"
        "      <complexType name=\"tDatiFondiFault\">\n"
        "        <complexContent>\n"
        "          <extension base=\"tns1:Errore\">\n"
        "            <sequence/>\n"
        "          </extension>\n"
        "        </complexContent>\n"
        "      </complexType>\n"
        "      \n"
        "      <!-- Define element for proper fault definition -->\n"
        "      <element name=\"DatiFondiFaultElement\" type=\"intf:tDatiFondiFault\"/>\n"
        "    </schema>\n"
        "    \n"
        "    <schema elementFormDefault=\"qualified\" targetNamespace=\"it.objectway.owfs.external.data.impl\" xmlns=\"http://www.w3.org/2001/XMLSchema\">\n"
        "      <complexType name=\"listaPosizioni\">\n"
        "        <sequence>\n"
        "          <element maxOccurs=\"unbounded\" minOccurs=\"0\" name=\"item\" type=\"xsd:string\"/>\n"
        "        </sequence>\n"
        "      </complexType>\n"
        "    </schema>\n"
        "  </wsdl:types>\n"
        "  \n"
        "  <!-- Messages -->\n"
        "  <wsdl:message name=\"DatiFondiRequest\">\n"
        "    <wsdl:part name=\"DatiFondiRequest\" type=\"intf:BINDatiFondi\"/>\n"
        "  </wsdl:message>\n"
        "  \n"
        "  <wsdl:message name=\"DatiFondiResponse\">\n"
        "    <wsdl:part name=\"DatiFondiResponse\" type=\"intf:BOUDatiFondi\"/>\n"
        "  </wsdl:message>\n"
        "  \n"
        "  <!-- THE PROBLEMATIC FAULT MESSAGE: using type= instead of element= -->\n"
        "  <wsdl:message name=\"TDatiFondiFault\">\n"
        "    <wsdl:part name=\"DatiFondiFault\" type=\"intf:tDatiFondiFault\"/>  <!-- INVALID: should use element= -->\n"
        "  </wsdl:message>\n"
        "  \n"
        "  <!-- Port Type -->\n"
        "  <wsdl:portType name=\"DatiFondiServices\">\n"
        "    <wsdl:operation name=\"DatiFondi\" parameterOrder=\"DatiFondiRequest\">\n"
        "      <wsdl:input name=\"DatiFondiRequest\" message=\"impl:DatiFondiRequest\"/>\n"
        "      <wsdl:output name=\"DatiFondiResponse\" message=\"impl:DatiFondiResponse\"/>\n"
        "      <wsdl:fault name=\"TDatiFondiFault\" message=\"impl:TDatiFondiFault\"/>\n"
        "    </wsdl:operation>\n"
        "  </wsdl:portType>\n"
        "  \n"
        "  <!-- Binding -->\n"
        "  <wsdl:binding name=\"DatiFondiSOAPSoapBinding\" type=\"intf:DatiFondiServices\">\n"
        "    <wsdlsoap:binding style=\"rpc\" transport=\"http://schemas.xmlsoap.org/soap/http\"/>\n"
        "    <wsdl:operation name=\"DatiFondi\">\n"
        "      <wsdlsoap:operation soapAction=\"http://es.ubi.it/srv/analysis/DatiFondi\"/>\n"
        "      <wsdl:input name=\"DatiFondiRequest\">\n"
        "        <wsdlsoap:body use=\"literal\" namespace=\"http://es.ubi.it/srv/analysis\"/>\n"
        "      </wsdl:input>\n"
        "      <wsdl:output name=\"DatiFondiResponse\">\n"
        "        <wsdlsoap:body use=\"literal\" namespace=\"http://es.ubi.it/srv/datifondi\"/>\n"
        "      </wsdl:output>\n"
        "      <wsdl:fault name=\"TDatiFondiFault\">\n"
        "        <wsdlsoap:fault name=\"TDatiFondiFault\" use=\"literal\"/>\n"
        "      </wsdl:fault>\n"
        "    </wsdl:operation>\n"
        "  </wsdl:binding>\n"
        "  \n"
        "  <!-- Service -->\n"
        "  <wsdl:service name=\"DatiFondiServices\">\n"
        "    <wsdl:port name=\"DatiFondiSOAP\" binding=\"intf:DatiFondiSOAPSoapBinding\">\n"
        "      <wsdlsoap:address location=\"http://192.168.132.231:9081/FFWsPcf/services/DatiFondiSOAP\"/>\n"
        "    </wsdl:port>\n"
        "  </wsdl:service>\n"
        "</wsdl:definitions>\n";

    /* Ensure directories exist and clean output */
    int mkdir_result = system("mkdir -p wsdl output/axis2c_1658_invalid_fault_test");
    if (mkdir_result != 0) {
        printf("Warning: Failed to create directories (exit code: %d)\n", mkdir_result);
    }

    /* Clean any existing output to avoid conflicts */
    int clean_result = system("rm -rf output/axis2c_1658_invalid_fault_test/*");
    if (clean_result != 0) {
        printf("Warning: Failed to clean output directory (exit code: %d)\n", clean_result);
    }

    /* Write test WSDL with invalid fault definition */
    FILE *wsdl_file = fopen("wsdl/axis2c_1658_invalid_fault_test.wsdl", "w");
    ADB_ASSERT_NOT_NULL(wsdl_file, "Could not create AXIS2C-1658 test WSDL file");

    fputs(invalid_fault_wsdl, wsdl_file);
    fclose(wsdl_file);

    /* Verify WSDL was written correctly */
    printf("=== DEBUG: AXIS2C-1658 Invalid Fault WSDL created ===\n");
    int head_result = system("head -20 wsdl/axis2c_1658_invalid_fault_test.wsdl");
    if (head_result != 0) {
        printf("Warning: Could not verify WSDL content (exit code: %d)\n", head_result);
    }

    /* Verify the problematic fault pattern is present */
    int pattern_result = system("grep -c 'type=\"intf:tDatiFondiFault\"' wsdl/axis2c_1658_invalid_fault_test.wsdl");
    if (pattern_result != 0) {
        printf("Info: Fault pattern verification completed (exit code: %d)\n", pattern_result);
    }

    /* Test code generation - expect this to potentially fail with validation error */
    printf("=== AXIS2C-1658 CRITICAL TEST: Testing Native WSDL2C Fault Validation ===\n");
    adb_test_result_t result = adb_test_code_generation(&test_config);

    if (result == ADB_TEST_SUCCESS) {
        printf("✅ AXIS2C-1658 NATIVE DIFFERENCE: Native WSDL2C accepts invalid fault definition\n");
        printf("   This differs from Java WSDL2Java which rejects type= in fault messages\n");
        printf("   Native generator may be more permissive with WSDL validation\n");

        /* If code generation succeeded, test compilation */
        result = adb_test_compile_generated_code(test_config.output_dir);
        if (result == ADB_TEST_SUCCESS) {
            printf("✅ AXIS2C-1658 COMPILATION: Generated code compiles successfully\n");
            printf("   Despite invalid WSDL, native generator produces working code\n");
        } else {
            printf("❌ AXIS2C-1658 COMPILATION: Generated code failed to compile\n");
            printf("   Invalid fault definition may cause compilation issues\n");
        }
    } else {
        printf("❌ AXIS2C-1658 VALIDATION: Native WSDL2C rejects invalid fault definition\n");
        printf("   Same validation behavior as Java WSDL2Java\n");
        printf("   User needs to fix WSDL: change type= to element= in fault message\n");
    }

    printf("=== AXIS2C-1658 ANALYSIS COMPLETE ===\n");
    printf("   • Invalid WSDL fault definition tested\n");
    printf("   • Native vs Java validation behavior compared\n");
    printf("   • WSDL specification compliance verified\n");

    printf("🎯 AXIS2C-1658 RESOLUTION:\n");
    printf("   1. CLASSIFICATION: User error - invalid WSDL fault definition\n");
    printf("   2. FIX REQUIRED: Change fault message from type= to element=\n");
    printf("   3. CORRECT WSDL: <wsdl:part name=\"DatiFondiFault\" element=\"intf:DatiFondiFaultElement\"/>\n");
    printf("   4. STANDARD: WSDL fault messages must always use element= regardless of style\n");
    printf("   5. ENHANCEMENT: Better error messages could help users understand the issue\n");

    return ADB_TEST_SUCCESS;
}

/* Test case for correct fault definition (for comparison) */
adb_test_result_t test_axis2c_1658_valid_fault_definition(void) {
    printf("Testing AXIS2C-1658 comparison: Valid fault definition (element vs type)...\n");

    int mkdir_result, clean_result;
    adb_codegen_test_t test_config = {
        .wsdl_path = "wsdl/axis2c_1658_valid_fault_test.wsdl",
        .output_dir = "output/axis2c_1658_valid_fault_test",
        .databinding = "adb",
        .unwrap = 1,
        .server_side = 1
    };

    /* Create corrected WSDL with proper element= usage */
    const char *valid_fault_wsdl =
        "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
        "<wsdl:definitions xmlns:apachesoap=\"http://xml.apache.org/xml-soap\"\n"
        "                  xmlns:impl=\"http://es.ubi.it/srv/datifondi\"\n"
        "                  xmlns:intf=\"http://es.ubi.it/srv/datifondi\"\n"
        "                  xmlns:tns1=\"http://es.ubi.it/typ/cm\"\n"
        "                  xmlns:tns2=\"it.objectway.owfs.external.data.impl\"\n"
        "                  xmlns:wsdl=\"http://schemas.xmlsoap.org/wsdl/\"\n"
        "                  xmlns:wsdlsoap=\"http://schemas.xmlsoap.org/wsdl/soap/\"\n"
        "                  xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n"
        "                  targetNamespace=\"http://es.ubi.it/srv/datifondi\">\n"
        "  <wsdl:types>\n"
        "    <schema targetNamespace=\"http://es.ubi.it/srv/datifondi\" xmlns=\"http://www.w3.org/2001/XMLSchema\">\n"
        "      <import namespace=\"http://es.ubi.it/typ/cm\"/>\n"
        "      \n"
        "      <complexType name=\"tDatiFondiFault\">\n"
        "        <sequence>\n"
        "          <element name=\"id\" nillable=\"true\" type=\"xsd:string\"/>\n"
        "          <element name=\"tipo\" nillable=\"true\" type=\"xsd:string\"/>\n"
        "          <element name=\"messaggio\" nillable=\"true\" type=\"xsd:string\"/>\n"
        "          <element name=\"guid\" nillable=\"true\" type=\"xsd:string\"/>\n"
        "        </sequence>\n"
        "      </complexType>\n"
        "      \n"
        "      <!-- CORRECT: Define element for fault message -->\n"
        "      <element name=\"DatiFondiFaultElement\" type=\"intf:tDatiFondiFault\"/>\n"
        "      \n"
        "      <complexType name=\"TestRequest\">\n"
        "        <sequence>\n"
        "          <element name=\"input\" type=\"xsd:string\"/>\n"
        "        </sequence>\n"
        "      </complexType>\n"
        "      \n"
        "      <complexType name=\"TestResponse\">\n"
        "        <sequence>\n"
        "          <element name=\"output\" type=\"xsd:string\"/>\n"
        "        </sequence>\n"
        "      </complexType>\n"
        "    </schema>\n"
        "  </wsdl:types>\n"
        "  \n"
        "  <!-- Messages -->\n"
        "  <wsdl:message name=\"TestRequest\">\n"
        "    <wsdl:part name=\"TestRequest\" type=\"intf:TestRequest\"/>\n"
        "  </wsdl:message>\n"
        "  \n"
        "  <wsdl:message name=\"TestResponse\">\n"
        "    <wsdl:part name=\"TestResponse\" type=\"intf:TestResponse\"/>\n"
        "  </wsdl:message>\n"
        "  \n"
        "  <!-- CORRECT FAULT MESSAGE: using element= instead of type= -->\n"
        "  <wsdl:message name=\"TDatiFondiFault\">\n"
        "    <wsdl:part name=\"DatiFondiFault\" element=\"intf:DatiFondiFaultElement\"/>  <!-- CORRECT: using element= -->\n"
        "  </wsdl:message>\n"
        "  \n"
        "  <!-- Port Type -->\n"
        "  <wsdl:portType name=\"TestServices\">\n"
        "    <wsdl:operation name=\"TestOperation\" parameterOrder=\"TestRequest\">\n"
        "      <wsdl:input name=\"TestRequest\" message=\"impl:TestRequest\"/>\n"
        "      <wsdl:output name=\"TestResponse\" message=\"impl:TestResponse\"/>\n"
        "      <wsdl:fault name=\"TDatiFondiFault\" message=\"impl:TDatiFondiFault\"/>\n"
        "    </wsdl:operation>\n"
        "  </wsdl:portType>\n"
        "  \n"
        "  <!-- Binding -->\n"
        "  <wsdl:binding name=\"TestSOAPSoapBinding\" type=\"intf:TestServices\">\n"
        "    <wsdlsoap:binding style=\"rpc\" transport=\"http://schemas.xmlsoap.org/soap/http\"/>\n"
        "    <wsdl:operation name=\"TestOperation\">\n"
        "      <wsdlsoap:operation soapAction=\"http://es.ubi.it/srv/test/TestOperation\"/>\n"
        "      <wsdl:input name=\"TestRequest\">\n"
        "        <wsdlsoap:body use=\"literal\" namespace=\"http://es.ubi.it/srv/test\"/>\n"
        "      </wsdl:input>\n"
        "      <wsdl:output name=\"TestResponse\">\n"
        "        <wsdlsoap:body use=\"literal\" namespace=\"http://es.ubi.it/srv/datifondi\"/>\n"
        "      </wsdl:output>\n"
        "      <wsdl:fault name=\"TDatiFondiFault\">\n"
        "        <wsdlsoap:fault name=\"TDatiFondiFault\" use=\"literal\"/>\n"
        "      </wsdl:fault>\n"
        "    </wsdl:operation>\n"
        "  </wsdl:binding>\n"
        "  \n"
        "  <!-- Service -->\n"
        "  <wsdl:service name=\"TestServices\">\n"
        "    <wsdl:port name=\"TestSOAP\" binding=\"intf:TestSOAPSoapBinding\">\n"
        "      <wsdlsoap:address location=\"http://localhost:8080/services/TestSOAP\"/>\n"
        "    </wsdl:port>\n"
        "  </wsdl:service>\n"
        "</wsdl:definitions>\n";

    /* Ensure directories exist and clean output */
    mkdir_result = system("mkdir -p wsdl output/axis2c_1658_valid_fault_test");
    if (mkdir_result != 0) {
        printf("Warning: Failed to create directories (exit code: %d)\n", mkdir_result);
    }

    /* Clean any existing output to avoid conflicts */
    clean_result = system("rm -rf output/axis2c_1658_valid_fault_test/*");
    if (clean_result != 0) {
        printf("Warning: Failed to clean output directory (exit code: %d)\n", clean_result);
    }

    /* Write test WSDL with valid fault definition */
    FILE *wsdl_file = fopen("wsdl/axis2c_1658_valid_fault_test.wsdl", "w");
    ADB_ASSERT_NOT_NULL(wsdl_file, "Could not create AXIS2C-1658 valid test WSDL file");

    fputs(valid_fault_wsdl, wsdl_file);
    fclose(wsdl_file);

    /* Test code generation - this should succeed */
    printf("=== AXIS2C-1658 COMPARISON: Testing valid fault definition ===\n");
    adb_test_result_t result = adb_test_code_generation(&test_config);
    ADB_ASSERT_TRUE(result == ADB_TEST_SUCCESS, "AXIS2C-1658 valid fault code generation failed");

    /* Test compilation of generated code */
    result = adb_test_compile_generated_code(test_config.output_dir);
    ADB_ASSERT_TRUE(result == ADB_TEST_SUCCESS, "AXIS2C-1658 valid fault compilation failed");

    printf("✅ AXIS2C-1658 COMPARISON: Valid fault definition works correctly\n");
    printf("   • Proper element= usage in fault message\n");
    printf("   • Code generation successful\n");
    printf("   • Generated code compiles without issues\n");

    return ADB_TEST_SUCCESS;
}

/* Test case list for AXIS2C-1658 */
adb_test_case_t axis2c_1658_tests[] = {
    {
        .name = "test_axis2c_1658_invalid_fault_definition",
        .description = "Test AXIS2C-1658: WSDL fault validation (invalid type= usage)",
        .test_func = test_axis2c_1658_invalid_fault_definition
    },
    {
        .name = "test_axis2c_1658_valid_fault_definition",
        .description = "Test AXIS2C-1658: WSDL fault validation (correct element= usage)",
        .test_func = test_axis2c_1658_valid_fault_definition
    }
};

int axis2c_1658_test_count = sizeof(axis2c_1658_tests) / sizeof(adb_test_case_t);