package com.steerinfo.meterwork.meterworkmonitor.service;

import com.steerinfo.meterwork.meterworkmonitor.mapper.MeterWorkMonitorMapper;
import com.steerinfo.meterwork.meterworkmonitor.model.MeterWorkMonitor;
import com.steerinfo.meterwork.meterworkmonitor.rtdb.MeterWorkMonitorRtdbRepository;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;

/**
 * 将 Tarantool METER_WORK_MONITOR 脏数据回写 Oracle。
 */
@Service
@ConditionalOnExpression("'${rtdb.monitor.enabled:true}' == 'true' && '${meter.monitor.sync.enabled:false}' == 'true'")
public class MeterWorkMonitorSyncService {

    private static final Logger log = LoggerFactory.getLogger(MeterWorkMonitorSyncService.class);

    private final AtomicBoolean running = new AtomicBoolean(false);

    @Resource
    private MeterWorkMonitorRtdbRepository meterWorkMonitorRtdbRepository;

    @Resource
    private MeterWorkMonitorMapper meterWorkMonitorMapper;

    public void doSync() {
        if (!running.compareAndSet(false, true)) {
            log.warn("MeterWorkMonitor sync skipped: previous run still in progress");
            return;
        }
        long start = System.currentTimeMillis();
        int success = 0;
        int failed = 0;
        try {
            List<MeterWorkMonitor> dirtyRows = meterWorkMonitorRtdbRepository.selectDirty();
            log.info("MeterWorkMonitor sync start, dirtyCount={}", dirtyRows.size());
            if (dirtyRows.isEmpty()) {
                return;
            }
            for (MeterWorkMonitor row : dirtyRows) {
                try {
                    meterWorkMonitorMapper.updateByPrimaryKeySelective(row);
                    meterWorkMonitorRtdbRepository.clearDirty(row.getPointNo());
                    success++;
                } catch (Exception ex) {
                    failed++;
                    log.error("sync row failed, pointNo={}", row.getPointNo(), ex);
                }
            }
        } catch (Exception e) {
            log.error("MeterWorkMonitor sync failed", e);
        } finally {
            running.set(false);
            log.info("MeterWorkMonitor sync done, success={}, failed={}, costMs={}",
                    success, failed, System.currentTimeMillis() - start);
        }
    }
}
