package me.km.blockprotections;

import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import me.km.KajetansMod;
import me.km.databank.DataBank;
import me.km.overrides.ModEntityPlayerMP;
import me.km.world.WorldManager;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.IWorld;

public class BlockProtectionBank implements IBlockProtection
{  
    private final PreparedStatement hasAccess;
    private final PreparedStatement getId;
    
    public BlockProtectionBank(DataBank databank) 
    {
        databank.execute("CREATE TABLE IF NOT EXISTS block ("
                    + "id INT NOT NULL AUTO_INCREMENT PRIMARY KEY, "
                    + "x int(11) NOT NULL, "
                    + "y int(11) NOT NULL, "
                    + "z int(11) NOT NULL, "
                    + "world_name varchar(20) NOT NULL, "
                    + "UNIQUE KEY uniq_block_pos (world_name,x,y,z));");
        
        databank.execute("CREATE TABLE IF NOT EXISTS block_grant ("
                    + "id INT NOT NULL AUTO_INCREMENT PRIMARY KEY, "
                    + "block_id int(11) NOT NULL, "
                    + "player_id int(11) NOT NULL, "
                    + "INDEX block_id (block_id), "
                    + "UNIQUE KEY (block_id, player_id), "
                    + "CONSTRAINT block_grant_ibfk_1 FOREIGN KEY (block_id) REFERENCES block (id) ON DELETE CASCADE);");
        
        hasAccess = databank.prepareStatement("Select id from block_grant WHERE id = ? AND player_id = ?;");
        getId = databank.prepareStatement("SELECT id FROM block WHERE world_name=? AND x=? AND y=? AND z=?;");
    }  

    @Override
    public boolean hasAccess(int x, int y, int z, String worldName, int playerId)
    {
        int id = getId(x, y, z, worldName);
        if(id == -1)
        {
            return true;
        }
        try
        {
            hasAccess.setInt(1, id);
            hasAccess.setInt(2, playerId);
            try(ResultSet rs = hasAccess.executeQuery())
            {
                return rs.next();
            }
            catch(SQLException ex)
            {
                ex.printStackTrace();
            }
        }
        catch(SQLException ex)
        {
            ex.printStackTrace();
        }
        return false;
    }
    
    @Override
    public boolean hasAccess(BlockPos pos, IWorld w, ModEntityPlayerMP p)
    {
        return hasAccess(pos.getX(), pos.getY(), pos.getZ(), WorldManager.getName(w), p.getId());
    }

    private int getId(int x, int y, int z, String worldName)
    {
        try
        {
            getId.setString(1, worldName);
            getId.setInt(2, x);
            getId.setInt(3, y);
            getId.setInt(4, z);
            try(ResultSet rs = getId.executeQuery())
            {
                if(rs.next())
                {
                    return rs.getInt(1);
                }
                return -1;
            }
            catch(SQLException ex)
            {
                ex.printStackTrace();
            }
        }
        catch(SQLException ex)
        {
            ex.printStackTrace();
        }
        return -1;
    }
}