{#     Copyright 2023, Kay Hayen, mailto:kay.hayen@gmail.com                    #}
{#                                                                              #}
{#     Python test originally created or extracted from other peoples work. The #}
{#     parts from me are licensed as below. It is at least Free Software where  #}
{#     it's copied from other people. In these cases, that will normally be     #}
{#     indicated.                                                               #}
{#                                                                              #}
{#     Licensed 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.                                           #}
{#                                                                              #}

# This test does check operations in optimizable and not optimizable forms
# to check for proper errors, exceptions, etc.

from __future__ import print_function

# Function to hide type because it is not seen through
def forgetType(value):
    return value


{% for op_name, operation in operations %}
{% for l_type, left_1, left_2 in candidates %}
{% for r_type, right_1, right_2 in candidates %}

{% set operation_id = op_name + "_" + l_type + "_" + r_type %}

def {{operation_id}}(cond):
    # First value, which we expect to be compile time computed.
    left = {{left_1}}
    right = {{right_1}}

    try:
        x = {{makeOperatorUsage(operation, "left", "right")}}
    except Exception as e: # pylint: disable=broad-except
        print("{{operation_id}} compile time occurred:", e)
    else:
        print("{{operation_id}} compile time result:", x)

    # Second value, which we expect to be compile time computed as well.
    left = {{left_2}}
    right = {{right_2}}

    try:
        # We expect this to be compile time computed.
        x = {{makeOperatorUsage(operation, "left", "right")}}
    except Exception as e: # pylint: disable=broad-except
        print("{{operation_id}} compile time occurred:", e)
    else:
        print("{{operation_id}} compile time result:", x)

    # Now the branch may make things less clear for mixed types and
    # also require the operation to be checked at run time.
    left = {{left_1}} if cond else {{left_2}}
    right = {{right_1}} if cond else {{right_2}}

    try:
        # We expect this to be compile time error checked still.
        x = {{makeOperatorUsage(operation, "left", "right")}}
    except Exception as e: # pylint: disable=broad-except
        print("{{operation_id}} runtime occurred:", e)
    else:
        print("{{operation_id}} runtime result:", x)

    # Now we forget one type, forcing run time error checking.
    left = forgetType({{left_1}})
    right = {{right_1}}

    try:
        x = {{makeOperatorUsage(operation, "left", "right")}}
    except Exception as e: # pylint: disable=broad-except
        print("{{operation_id}} runtime occurred:", e)
    else:
        print("{{operation_id}} runtime result:", x)

    # And the other, forcing run time error checking.
    left = {{left_1}}
    right = forgetType({{right_1}})

    try:
        # We expect this to be compile time error checked still.
        x = {{makeOperatorUsage(operation, "left", "right")}}
    except Exception as e: # pylint: disable=broad-except
        print("{{operation_id}} runtime occurred:", e)
    else:
        print("{{operation_id}} runtime result:", x)

    # And both, forcing generic run time error checking.
    left = forgetType({{left_1}})
    right = forgetType({{right_1}})

    try:
        # We expect this to be compile time error checked still.
        x = {{makeOperatorUsage(operation, "left", "right")}}
    except Exception as e: # pylint: disable=broad-except
        print("{{operation_id}} runtime occurred:", e)
    else:
        print("{{operation_id}} runtime result:", x)

{{operation_id}}(1)
{{operation_id}}(0)

{% endfor %}
{% endfor %}
{% endfor %}
