/*
 * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
 * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
 */

package javasoft.sqe.tests.api.java.lang.classfile.resources;

import java.lang.annotation.Repeatable;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;

import static java.lang.annotation.ElementType.*;

public abstract class TestMethods0<E extends Object> {

    static List<String> slist;

    static {
        slist = new ArrayList<>(25);
        for (int i = 0; i < 25; i++) {
            slist.set(i, Integer.toString(i+1));
        }
    }

    @MethodAnnot(dvalue = 0f)
    public TestMethods0() {

    }

    @MethodAnnot(cvalue = TestMethods0.class)
    private final void empty0() {
    }

    @MethodAnnot(fvalue = 0f)
    private static void empty1() {
    }

    @IFooContainer({@IFoo(1)}) @IFooContainer({@IFoo(2)})
    public int retI() {
        return 1;
    }

    public static String retS() {
        return "string";
    }

    protected abstract Map<List<E>, Outer.Middle<@TestFields0.A Foo.@TestFields0.B Bar>.Inner<@TestFields0.D String @TestFields0.C []>>
    sum0(@MethodAnnot(cvalue = Hashtable.class) List<Outer.Middle<@TestFields0.A Foo.@TestFields0.B Bar>.Inner<@TestFields0.D String @TestFields0.C []>> A);

    protected final static int sum1(@MethodAnnot(ivalue = 0xa) int a, short b, @MethodAnnot(svalue = "c") String c, @MethodAnnot(lvalue = 0xdl) long d) {
        return a + (int)b + Integer.valueOf(c) + (int) d;
    }

    @Target({METHOD})
    @Retention(RetentionPolicy.RUNTIME)
    @Repeatable(IFooContainer.class)
    @interface IFoo {
        int value();
    }

    @Target({METHOD})
    @Retention(RetentionPolicy.RUNTIME)
    @Repeatable(IFooContainerContainer.class)
    @interface IFooContainer {
        IFoo[] value();
    }

    @Target({METHOD})
    @Retention(RetentionPolicy.RUNTIME)
    @interface IFooContainerContainer {
        IFooContainer[] value();
    }

    @Target({METHOD, PARAMETER, CONSTRUCTOR})
    @Retention(RetentionPolicy.RUNTIME)
    public @interface MethodAnnot {
        int ivalue() default 1;

        long lvalue() default 1l;

        float fvalue() default 1.1f;

        double dvalue() default 2.2f;

        Class<? extends Object> cvalue() default RuntimeException.class;

        String svalue() default " ";

        EMType evalue() default EMType.METHOD_TYPE_A;
    }

    protected enum EMType {
        METHOD_TYPE_A, METHOD_TYPE_B, METHOD_TYPE_C;
    }

    static class Foo {
        class Bar {
        }
    }

    class Outer {
        class Middle<T> {
            class Inner<U> {
            }
        }
    }
}
