package com.sy.coinage.monitor;

import java.util.*;

import com.sy.coinage.monitor.req.CacheKeysReq;
import com.sy.coinage.monitor.req.CacheUpdateReq;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;

/**
 * -缓存监控
 *
 * @author lug
 */
@RestController
@RequestMapping("/monitor/cache")
public class CacheController {

    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    @GetMapping()
    public Object getInfo() throws Exception {
        Properties info = (Properties) redisTemplate.execute((RedisCallback<Object>) connection -> connection.info());
        Properties commandStats = (Properties) redisTemplate
                        .execute((RedisCallback<Object>) connection -> connection.info("commandstats"));
        Object dbSize = redisTemplate.execute((RedisCallback<Object>) connection -> connection.dbSize());
        Map<String, Object> data = new HashMap<>(3);
        data.put("info", info);
        data.put("dbSize", dbSize);
        List<Map<String, String>> pieList = new ArrayList<>();
        commandStats.stringPropertyNames().forEach(key -> {
            Map<String, String> d = new HashMap<>(2);
            String property = commandStats.getProperty(key);
            d.put("name", StringUtils.removeStart(key, "cmdstat_"));
            d.put("value", StringUtils.substringBetween(property, "calls=", ",usec"));
            pieList.add(d);
        });
        data.put("commandStats", pieList);
        return data;
    }

    @PostMapping("/keys")
    public Object keys(@RequestBody CacheKeysReq req) throws Exception {
        String key = "*";
        if (StringUtils.isNotBlank(req.getKey())) {
            key = "*" + req.getKey() + "*";
        }
        Set<String> set = this.redisTemplate.keys(key);
        List data = Arrays.asList(set.toArray());
        Collections.sort(data, new Comparator<String>() {
            @Override
            public int compare(String arg0, String arg1) {
                return arg0.charAt(0) - arg1.charAt(0);
            }
        });
        return data;
    }

    @PostMapping("/get")
    public Object get(@RequestBody @Valid CacheKeysReq req) throws Exception {
        String resp = null;
        if (this.redisTemplate.hasKey(req.getKey())) {
            resp = this.redisTemplate.opsForValue().get(req.getKey());
        }
        if (resp.startsWith("\"")) {
            resp = resp.substring(1);
        }
        if (resp.endsWith("\"")) {
            resp = resp.substring(0, resp.length() - 1);
        }
        return resp;
    }

    @PostMapping("/delete")
    public Object delete(@RequestBody @Valid CacheKeysReq req) throws Exception {
        if (this.redisTemplate.hasKey(req.getKey())) {
            this.redisTemplate.delete(req.getKey());
        }
        return null;
    }

    @PostMapping("/update")
    public Object update(@RequestBody @Valid CacheUpdateReq req) throws Exception {
        if (this.redisTemplate.hasKey(req.getKey())) {
            this.redisTemplate.opsForValue().set(req.getKey(), req.getValue());
        }
        return null;
    }

}
