package com.ruoyi.file.service;

import com.alibaba.fastjson2.JSON;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.spring.SpringUtils;
import com.ruoyi.file.object.ProjectState;
import com.ruoyi.file.object.RuntimeState;
import com.ruoyi.file.object.StateMachine;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import java.util.List;
import java.util.Map;

@Service
@Slf4j
public class StateService
{
    private static final String STATE_MACHINE_KEY = "STATE_MACHINE";

    public ProjectState detail(String token)
    {
        return StateMachine.INSTANCE.GetState(token);
    }

    public List<ProjectState> list()
    {
        return StateMachine.INSTANCE.GetStates();
    }

    public RuntimeState runtimeState()
    {
        return RuntimeState.capture();
    }

    public long gc()
    {
        StateMachine.INSTANCE.GC();
        dump();
        System.gc();
        init();
        return StateMachine.INSTANCE.gcCount;
    }

    public StateMachine stateMachine()
    {
        return StateMachine.INSTANCE;
    }

    public void dump()
    {
        StateMachine.INSTANCE.Save();
        save();
    }

    private void save()
    {
        try
        {
            Map<?, ?> map = StateMachine.INSTANCE.ToMap();
            String json = JSON.toJSONString(map);
            RedisCache redisCache = SpringUtils.getBean(RedisCache.class);
            redisCache.setCacheObject(STATE_MACHINE_KEY, json);
            log.info("备份持久化状态机信息: ");
            log.info(StateMachine.INSTANCE.ToString("; "));
        }
        catch(Exception e)
        {
            e.printStackTrace();
        }
    }

    @PostConstruct
    public void init()
    {
        try
        {
            RedisCache redisCache = SpringUtils.getBean(RedisCache.class);
            String stateMachine = redisCache.getCacheObject(STATE_MACHINE_KEY);
            if(StringUtils.isNotEmpty(stateMachine))
            {
                Map<?, ?> map = JSON.parseObject(stateMachine, Map.class);
                StateMachine.INSTANCE.FromMap(map);
                log.info("读取持久化状态机信息: ");
                log.info(StateMachine.INSTANCE.ToString("; "));
            }
        }
        catch(Exception e)
        {
            e.printStackTrace();
        }
    }

    @PreDestroy
    public void destroy()
    {
        StateMachine.INSTANCE.Finish();
        save();
    }
}
