// <copyright file="ComprehensiveCaller.cs" company="OpenTelemetry Authors">
// Copyright The OpenTelemetry Authors
//
// 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.
// </copyright>

namespace TestApplication.ExampleLibrary.GenericTests;

public class ComprehensiveCaller<CallerT1, CallerT2>
{
    #region CallReturnM1
    public void CallReturnM1WithCallerTypeArgs(GenericTarget<CallerT1, CallerT2> target, CallerT1 input1, CallerT2 input2)
    {
        target.ReturnM1<CallerT1, CallerT2>(input1, input2);
    }

    public void CallReturnM1WithCallerTypeArgsReversed(GenericTarget<CallerT1, CallerT2> target, CallerT1 input1, CallerT2 input2)
    {
        target.ReturnM1<CallerT2, CallerT1>(input2, input1);
    }

    public void CallReturnM1WithClass(GenericTarget<CallerT1, CallerT2> target, Exception input1, CallerT2 input2)
    {
        target.ReturnM1<Exception, CallerT2>(input1, input2);
    }

    public void CallReturnM1WithStruct(GenericTarget<CallerT1, CallerT2> target, PointStruct input1, CallerT2 input2)
    {
        target.ReturnM1<PointStruct, CallerT2>(input1, input2);
    }

    public void CallReturnM1WithReferenceTypeGenericInstantiation(GenericTarget<CallerT1, CallerT2> target, Task<Exception> input1, CallerT2 input2)
    {
        target.ReturnM1<Task<Exception>, CallerT2>(input1, input2);
    }

    public void CallReturnM1WithValueTypeGenericInstantiation(GenericTarget<CallerT1, CallerT2> target, StructContainer<Exception> input1, CallerT2 input2)
    {
        target.ReturnM1<StructContainer<Exception>, CallerT2>(input1, input2);
    }
    #endregion

    #region CallReturnM2
    public void CallReturnM2WithCallerTypeArgs(GenericTarget<CallerT1, CallerT2> target, CallerT1 input1, CallerT2 input2)
    {
        target.ReturnM2<CallerT1, CallerT2>(input1, input2);
    }

    public void CallReturnM2WithCallerTypeArgsReversed(GenericTarget<CallerT1, CallerT2> target, CallerT1 input1, CallerT2 input2)
    {
        target.ReturnM2<CallerT2, CallerT1>(input2, input1);
    }

    public void CallReturnM2WithClass(GenericTarget<CallerT1, CallerT2> target, CallerT1 input1, Exception input2)
    {
        target.ReturnM2<CallerT1, Exception>(input1, input2);
    }

    public void CallReturnM2WithStruct(GenericTarget<CallerT1, CallerT2> target, CallerT1 input1, PointStruct input2)
    {
        target.ReturnM2<CallerT1, PointStruct>(input1, input2);
    }

    public void CallReturnM2WithReferenceTypeGenericInstantiation(GenericTarget<CallerT1, CallerT2> target, CallerT1 input1, Task<Exception> input2)
    {
        target.ReturnM2<CallerT1, Task<Exception>>(input1, input2);
    }

    public void CallReturnM2WithValueTypeGenericInstantiation(GenericTarget<CallerT1, CallerT2> target, CallerT1 input1, StructContainer<Exception> input2)
    {
        target.ReturnM2<CallerT1, StructContainer<Exception>>(input1, input2);
    }
    #endregion

    #region CallReturnT1
    public void CallReturnT1WithCallerTypeArgs(GenericTarget<CallerT1, CallerT2> target, object input)
    {
        target.ReturnT1(input);
    }

    public void CallReturnT1WithCallerTypeArgsReversed(GenericTarget<CallerT2, CallerT1> target, object input)
    {
        target.ReturnT1(input);
    }

    public void CallReturnT1WithClass(GenericTarget<Exception, CallerT2> target, object input)
    {
        target.ReturnT1(input);
    }

    public void CallReturnT1WithStruct(GenericTarget<PointStruct, CallerT2> target, object input)
    {
        target.ReturnT1(input);
    }

    public void CallReturnT1WithReferenceTypeGenericInstantiation(GenericTarget<Task<Exception>, CallerT2> target, object input)
    {
        target.ReturnT1(input);
    }

    public void CallReturnT1WithValueTypeGenericInstantiation(GenericTarget<StructContainer<Exception>, CallerT2> target, object input)
    {
        target.ReturnT1(input);
    }
    #endregion

    #region CallReturnT2
    public void CallReturnT2WithCallerTypeArgs(GenericTarget<CallerT1, CallerT2> target, object input)
    {
        target.ReturnT2(input);
    }

    public void CallReturnT2WithCallerTypeArgsReversed(GenericTarget<object, CallerT1> target, object input)
    {
        target.ReturnT2(input);
    }

    public void CallReturnT2WithClass(GenericTarget<int, Exception> target, object input)
    {
        target.ReturnT2(input);
    }

    public void CallReturnT2WithStruct(GenericTarget<StructContainer<Exception>, PointStruct> target, object input)
    {
        target.ReturnT2(input);
    }

    public void CallReturnT2WithReferenceTypeGenericInstantiation(GenericTarget<Task<Task<Task<Exception>>>, Task<Exception>> target, object input)
    {
        target.ReturnT2(input);
    }

    public void CallReturnT2WithValueTypeGenericInstantiation(GenericTarget<PointStruct, StructContainer<Exception>> target, object input)
    {
        target.ReturnT2(input);
    }
    #endregion
}
