/* 
    This file is a part of the SteamWar software.
    
    Copyright (C) 2020  SteamWar.de-Serverteam

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU Affero General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    GNU Affero General Public License for more details.

    You should have received a copy of the GNU Affero General Public License
    along with this program.  If not, see <https://www.gnu.org/licenses/>.
*/

package de.steamwar.velocitycore;

import de.steamwar.sql.SchematicType;
import lombok.Getter;

import java.util.*;

public class ArenaMode extends GameModeConfig {

    private static final Random random = new Random();

    private static final Map<String, ArenaMode> byChat = new HashMap<>();
    private static final Map<String, ArenaMode> byInternal = new HashMap<>();
    private static final Map<SchematicType, ArenaMode> bySchemType = new HashMap<>();
    @Getter
    private static final List<ArenaMode> allModes = new LinkedList<>();

    static {
        init();
    }

    public static void init() {
        byChat.clear();
        byInternal.clear();
        bySchemType.clear();
        allModes.clear();

        GameModeConfig.loadAll(ArenaMode.class, (file, mode) -> {
            if(mode.getServer() == null)
                return;

            mode.config = file.getName();
            mode.internalName = file.getName().replace(".yml", "");
            mode.getMaps().forEach(map -> mode.lowerToRealMapNames.put(map.toLowerCase(), map));
            if(mode.getGameName() == null)
                mode.setGameName(mode.internalName);

            allModes.add(mode);
            byInternal.put(mode.internalName, mode);
            for(String name : mode.getServer().getChatNames()){
                byChat.put(name.toLowerCase(), mode);
            }

            if(mode.getSchematic() != null && mode.getSchemType() != null)
                bySchemType.put(SchematicType.fromDB(mode.getSchemType()), mode);
        });
    }

    public static ArenaMode getByChat(String name){
        return byChat.get(name.toLowerCase());
    }

    public static ArenaMode getByInternal(String name){
        return byInternal.get(name);
    }

    public static List<String> getAllChatNames(boolean historic) {
        List<String> chatNames = new LinkedList<>();
        for(ArenaMode mode : byInternal.values()){
            if(historic == mode.isHistoric())
                chatNames.addAll(mode.getServer().getChatNames());
        }
        return chatNames;
    }

    public static ArenaMode getBySchemType(SchematicType schemType){
        return bySchemType.get(schemType);
    }


    private final Map<String, String> lowerToRealMapNames = new HashMap<>();

    @Getter
    private String internalName;
    @Getter
    private String config;

    public String hasMap(String map){
        for(String m : getMaps()) {
            if(m.equalsIgnoreCase(map))
                return m;
        }
        return null;
    }

    public String getRandomMap(){
        return getMaps().get(random.nextInt(getMaps().size()));
    }

    public String convertToRealMapName(String map){
        return lowerToRealMapNames.get(map.toLowerCase());
    }

    public String getChatName(){
        return getServer().getChatNames().get(0);
    }

    public boolean withoutChatName(){
        return getServer().getChatNames().isEmpty();
    }

    public String getSchemTypeOrInternalName() {
        Schematic schematic = getSchematic();
        if (schematic == null) {
            return internalName;
        }
        return schematic.getType();
    }
}
