package com.qaup.collision.common.model.base;

/**
 * 缓存常量定义类
 * 统一管理所有Redis缓存相关的键前缀、过期时间等常量
 */
public class CacheConstants {

    // ==================== 键前缀定义 ====================
    
    /**
     * 车辆位置缓存键前缀
     */
    public static final String VEHICLE_LOCATION_PREFIX = "vehicle:location:";
    
    /**
     * 车辆最新位置缓存键前缀
     */
    public static final String VEHICLE_LATEST_PREFIX = "vehicle:latest:";
    
    /**
     * 车辆轨迹缓存键前缀
     */
    public static final String VEHICLE_TRAJECTORY_PREFIX = "vehicle:trajectory:";
    
    /**
     * 机场区域配置缓存键前缀
     */
    public static final String AIRPORT_AREA_PREFIX = "area:config:";
    
    /**
     * 区域类型缓存键前缀
     */
    public static final String AREA_TYPE_PREFIX = "area:type:";
    
    /**
     * 空间查询结果缓存键前缀
     */
    public static final String SPATIAL_QUERY_PREFIX = "spatial:query:";
    
    /**
     * 包含点查询缓存键前缀
     */
    public static final String POINT_CONTAINS_PREFIX = "spatial:contains:";
    
    /**
     * 半径查询缓存键前缀
     */
    public static final String RADIUS_QUERY_PREFIX = "spatial:radius:";
    
    /**
     * 车辆统计缓存键前缀
     */
    public static final String VEHICLE_STATS_PREFIX = "stats:vehicle:";
    
    /**
     * 区域统计缓存键前缀
     */
    public static final String AREA_STATS_PREFIX = "stats:area:";
    
    /**
     * 冲突检测结果缓存键前缀
     */
    public static final String COLLISION_PREFIX = "collision:";
    
    /**
     * 地理网格缓存键前缀
     */
    public static final String GEO_GRID_PREFIX = "grid:";
    
    /**
     * 区域内载具缓存键前缀
     */
    public static final String VEHICLES_IN_AREA_PREFIX = "vehicles:area:";

    // ==================== 过期时间定义（秒） ====================
    
    /**
     * 车辆位置缓存过期时间：60秒
     * 车辆位置数据实时性要求高，设置较短过期时间
     */
    public static final long VEHICLE_LOCATION_EXPIRE = 60L;
    
    /**
     * 车辆最新位置缓存过期时间：30秒
     * 最新位置更新频繁，设置更短过期时间
     */
    public static final long VEHICLE_LATEST_EXPIRE = 30L;
    
    /**
     * 车辆轨迹缓存过期时间：300秒（5分钟）
     * 轨迹数据变化相对较慢
     */
    public static final long VEHICLE_TRAJECTORY_EXPIRE = 300L;
    
    /**
     * 机场区域配置缓存过期时间：3600秒（1小时）
     * 区域配置变化很少，可以设置较长过期时间
     */
    public static final long AIRPORT_AREA_EXPIRE = 3600L;
    
    /**
     * 空间查询结果缓存过期时间：120秒（2分钟）
     * 空间查询结果依赖于车辆位置，设置中等过期时间
     */
    public static final long SPATIAL_QUERY_EXPIRE = 120L;
    
    /**
     * 点包含查询缓存过期时间：60秒
     * 点包含查询频繁，但结果相对稳定
     */
    public static final long POINT_CONTAINS_EXPIRE = 60L;
    
    /**
     * 半径查询缓存过期时间：90秒
     * 半径查询结果变化频繁
     */
    public static final long RADIUS_QUERY_EXPIRE = 90L;
    
    /**
     * 统计数据缓存过期时间：300秒（5分钟）
     * 统计数据不需要实时性
     */
    public static final long STATS_EXPIRE = 300L;
    
    /**
     * 冲突检测结果缓存过期时间：30秒
     * 冲突检测结果需要较高实时性
     */
    public static final long COLLISION_EXPIRE = 30L;
    
    /**
     * 地理网格缓存过期时间：600秒（10分钟）
     * 地理网格相对稳定
     */
    public static final long GEO_GRID_EXPIRE = 600L;

    // ==================== 缓存策略配置 ====================
    
    /**
     * 最大缓存条目数量
     */
    public static final int MAX_CACHE_ENTRIES = 10000;
    
    /**
     * 批量操作的批次大小
     */
    public static final int BATCH_SIZE = 100;
    
    /**
     * 地理网格精度（小数位数）
     * 用于地理坐标的网格化缓存
     */
    public static final int GEO_GRID_PRECISION = 4;
    
    /**
     * 缓存预热开关
     * 是否在应用启动时预热缓存
     */
    public static final boolean ENABLE_CACHE_WARMUP = true;
    
    /**
     * 缓存穿透保护开关
     * 是否启用缓存穿透保护机制
     */
    public static final boolean ENABLE_PENETRATION_PROTECTION = true;
    
    /**
     * 空值缓存时间：30秒
     * 用于缓存穿透保护
     */
    public static final long NULL_VALUE_EXPIRE = 30L;

    // ==================== 工具方法 ====================
    
    /**
     * 构建车辆位置缓存键
     */
    public static String buildVehicleLocationKey(Long vehicleId) {
        return VEHICLE_LOCATION_PREFIX + vehicleId;
    }
    
    /**
     * 构建车辆最新位置缓存键
     */
    public static String buildVehicleLatestKey(Long vehicleId) {
        return VEHICLE_LATEST_PREFIX + vehicleId;
    }
    
    /**
     * 构建车辆轨迹缓存键
     */
    public static String buildVehicleTrajectoryKey(Long vehicleId, long startTime, long endTime) {
        return VEHICLE_TRAJECTORY_PREFIX + vehicleId + ":" + startTime + ":" + endTime;
    }
    
    /**
     * 构建机场区域缓存键
     */
    public static String buildAirportAreaKey(String areaName) {
        return AIRPORT_AREA_PREFIX + areaName;
    }
    
    /**
     * 构建区域类型缓存键
     */
    public static String buildAreaTypeKey(String areaType) {
        return AREA_TYPE_PREFIX + areaType;
    }
    
    /**
     * 构建点包含查询缓存键
     */
    public static String buildPointContainsKey(double longitude, double latitude) {
        // 使用固定精度避免浮点数精度问题
        String lon = String.format("%.4f", longitude);
        String lat = String.format("%.4f", latitude);
        return POINT_CONTAINS_PREFIX + lon + ":" + lat;
    }
    
    /**
     * 构建半径查询缓存键
     */
    public static String buildRadiusQueryKey(double longitude, double latitude, double radius) {
        String lon = String.format("%.4f", longitude);
        String lat = String.format("%.4f", latitude);
        String rad = String.format("%.1f", radius);
        return RADIUS_QUERY_PREFIX + lon + ":" + lat + ":" + rad;
    }
    
    /**
     * 构建地理网格缓存键
     */
    public static String buildGeoGridKey(double longitude, double latitude) {
        // 将坐标转换为网格坐标
        int gridLon = (int) (longitude * Math.pow(10, GEO_GRID_PRECISION));
        int gridLat = (int) (latitude * Math.pow(10, GEO_GRID_PRECISION));
        return GEO_GRID_PREFIX + gridLon + ":" + gridLat;
    }
    
    /**
     * 构建冲突检测缓存键
     */
    public static String buildCollisionKey(Long vehicleId1, Long vehicleId2) {
        // 确保键的唯一性，较小的vehicleId在前
        if (vehicleId1.compareTo(vehicleId2) <= 0) {
            return COLLISION_PREFIX + vehicleId1 + ":" + vehicleId2;
        } else {
            return COLLISION_PREFIX + vehicleId2 + ":" + vehicleId1;
        }
    }
    
    /**
     * 构建空间查询缓存键
     */
    public static String buildSpatialQueryKey(String queryId) {
        return SPATIAL_QUERY_PREFIX + queryId;
    }
    
    /**
     * 私有构造函数，防止实例化
     */
    private CacheConstants() {
        throw new UnsupportedOperationException("This is a utility class and cannot be instantiated");
    }
} 