/*
 *   This file is a part of the SteamWar software.
 *
 *   Copyright (C) 2025 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.bausystem.region;

import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.bukkit.BukkitWorld;
import de.steamwar.bausystem.shared.SizedStack;
import lombok.NonNull;
import org.bukkit.Bukkit;

public interface RegionHistory {

    void remember(@NonNull EditSession editSession);

    boolean undo();

    boolean redo();

    RegionHistory EMPTY = new RegionHistory() {
        @Override
        public void remember(@NonNull EditSession editSession) {
        }

        @Override
        public boolean undo() {
            return false;
        }

        @Override
        public boolean redo() {
            return false;
        }
    };

    class Impl implements RegionHistory {

        private SizedStack<EditSession> undoSessions;
        private SizedStack<EditSession> redoSessions;

        public Impl(int size) {
            this.undoSessions = new SizedStack<>(size);
            this.redoSessions = new SizedStack<>(size);
        }

        @Override
        public void remember(@NonNull EditSession editSession) {
            undoSessions.push(editSession);
            if (redoSessions.empty()) return;
            redoSessions.clear();
        }

        @Override
        public boolean undo() {
            EditSession session = undoSessions.pop();
            if (session == null) return false;
            try (EditSession e = WorldEdit.getInstance().getEditSessionFactory().getEditSession(new BukkitWorld(Bukkit.getWorlds().get(0)), -1)) {
                session.undo(e);
                redoSessions.push(e);
            }
            return true;
        }

        @Override
        public boolean redo() {
            EditSession session = redoSessions.pop();
            if (session == null) return false;
            try (EditSession e = WorldEdit.getInstance().getEditSessionFactory().getEditSession(new BukkitWorld(Bukkit.getWorlds().get(0)), -1)) {
                session.redo(e);
                undoSessions.push(e);
            }
            return true;
        }
    }
}
