package game77.api;
// Příliš žluťoučký kůň úpěl ďábelské ó - PŘÍLIŠ ŽLUŤOUČKÝ KŮŇ ÚPĚL ĎÁBELSKÉ Ó
// J:/77_JAVA/game77/api/IPortal.java

import game77.testers.Level;
import game77.testers.PortalTester;

import java.lang.reflect.InvocationTargetException;
import java.util.List;



/*******************************************************************************
 * Instance interfejsu {@code IPortal} představují tovární objekty,
 * které jsou schopny na požádání dodat instance klíčových objektů aplikace,
 * konkrétně aktuální hry, jejích scénářů a uživatelského rozhraní.
 */
public interface IPortal
         extends IAuthor
{
//===== CLASS (STATIC) METHODS =================================================

    /***************************************************************************
     * Vrátí odkaz na instanci zadané tovární třídy. Předpokládá přitom,
     * že tato třída má dostupný nulární (= bezparametrický) konstruktor.
     *
     * @param <T>         Typ tovární třídy
     * @param portalClass Class-objekt tovární třídy
     * @return Požadovaný odkaz
     * @throws IllegalArgumentException Instanci zadané třídy
     *                                  se nepodařilo vytvořit
     */
    public static <T extends IPortal>
           T getInstanceOfFactory(Class<T> portalClass)
    {
        T result;
        try {
            result = portalClass.getDeclaredConstructor().newInstance();
        }
        catch (IllegalAccessException | IllegalArgumentException |
               InstantiationException | NoSuchMethodException    |
               SecurityException      | InvocationTargetException  ex)
        {
            throw new IllegalArgumentException(
                "\nNepodařilo se vytvořit instanci třídy " + portalClass, ex);
        }
        return result;
    }



//===== DEFAULT GETTERS AND SETTERS ============================================
/////// Metody vracející odkazy na klíčové objekty aplikace ///////

    /***************************************************************************
     * Vrátí seznam definovaných scénářů.
     * <ul>
     *   <li>
     *     Scénářem s indexem 0 musí být základní úspěšný scénář dané hry
     *     definující možný postup vedoucí k úspěšnému ukončení hry.<br>
     *     &nbsp;</li>
     *   <li>
     *     Scénářem s indexem 1 musí být základní povinný scénář, jenž definuje
     *     postup, při němž se demonstruje reakce na korektně zadané příkazy
     *     vyvolávající některou ze základní šestice povinných akcí.<br>
     *     &nbsp;</li>
     *   <li>
     *     Scénářem s indexem 2 musí být základní chybový scénář
     *     definující reakce hry na všechny možné uživatelské chyby
     *     při aktivaci některé ze základní šestice povinných akcí.<br>
     *     &nbsp;</li>
     *   <li>
     *     Scénářem s indexem 3 musí být nadstavbový chybový scénář
     *     definující reakce hry na všechny běžné uživatelské chyby
     *     specifikující reakce hry na možné uživatelské chyby
     *     při aktivaci některé rozšiřujících akcí.<br>
     *     &nbsp;</li>
     * </ul>
     * Výše uvedeným scénářům budou při jejich vytvářený automaticky
     * přiděleny předem definované názvy.
     * Názvy a účely dalších scénářů jsou již na libovůli autora.<br>
     *
     * @return Seznam spravovaných scénářů
     */
    //@Override
    default
    public List<Scenario> scenarios()
    {
        throw new UnsupportedOperationException("\nNení korektně definována "
                + "metoda scenarios()\nvracející seznam scénářů.");
    }


    /***************************************************************************
     * Vrátí odkaz na (jedinou) instanci textové verze hry;
     * dokud ještě hra neexistuje, vyhazuje po zavolání výjimku
     * {@link UnsupportedOperationException}.
     *
     * @return Požadovaný odkaz
     * @throws UnsupportedOperationException
     *         Potomek metodu korektně nepřebil
     */
    //@Override
    default
    public IGame game()
    {
        throw new UnsupportedOperationException(
              "\nNení korektně definována metoda game()"
            + "\nvracející instanci hry");
    }


//===== REMAINING DEFAULT METHODS ==============================================

    //Definované hladiny - na dané hladině se testuje:
    //PORTAL      = 0 #_ Jenom portál budoucí aplikace
    //HAPPY       = 1 #a Vytvoří předběžný šťastný scénář
    //DUPLET      = 2 #b Dva kompletní scénáře: HAPPY a BASIC
    //ARCHITECTURE= 3 #c Přítomnost požadovaných objektů a metod
    //START       = 4 #d Hra úspěšně odstartuje
    //WORLD       = 5 #e Hra úspěšně vybuduje svůj svět
    //BASIC       = 6 #f Zprovoznění standardních podle scénáře BASIC
    //TRIPLET     = 7 #g Přidán scénář MISTAKE
    //MISTAKES    = 8 #h Základní akce jsou navržené robustní
    //RUNNING     = 9 #i Zprovoznění běhu podle šťastného scénáře
    //QUADRUPLET  =10 #j Doplněn scénář HAPPY a přidán scénář MISTAKE_NS
    //WHOLE       =11 #k Úspěšné zprovoznění hry, všechny akce jsou robustní


    /***************************************************************************
     * Metoda testuje zadanou hladinu rozpracovanosti aplikace.
     * Proměnnou portal inicializujte instancí vašeho vlstního portálu.
     *
     * @param args Parametry příkazového řádku
     */
    public static void main(String[] args)
    {
        PortalTester.VERBOSE = false;
        var portal = getInstanceOfFactory(IPortal.class);  // new Portal();
        var tester = new PortalTester(portal, Level.PORTAL);
        tester.test();
    }

}
