package com.tsi.comm.server.process.dbms;

import com.tsi.app.common.app.AppUtils;
import com.tsi.comm.server.config.TsiCvimServerConfig;
import com.tsi.comm.server.process.AbstractTsiCvimProcess;
import com.tsi.comm.server.process.AbstractTsiCvimWorker;
import com.tsi.comm.server.repository.TsiNodeManager;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;

@Slf4j
@Getter
@Service
public class TsiCvimDbmsProcess extends AbstractTsiCvimProcess {

    public TsiCvimDbmsProcess() {
    }

    @PostConstruct
    void init() {
        ThreadGroup workerGroup = new ThreadGroup("dbmsProcess");
        TsiCvimServerConfig tsiCvimServerConfig = (TsiCvimServerConfig) AppUtils.getBean(TsiCvimServerConfig.class);

        this.workers = tsiCvimServerConfig.getDbmsWorkers();
        if (this.workers <= 0) this.workers = 1;
        int nodes = TsiNodeManager.getInstance().size();
        int qSize = tsiCvimServerConfig.getQueueSize();
        if (nodes > qSize) {
            qSize = nodes;
        }
        qSize *= 4;
        qSize /= this.workers;
        qSize = 1000;
        //this.workers = 1;
        for (int ii = 0; ii < this.workers; ii++) {
            TsiCvimDbmsWorker dbmsWorker = new TsiCvimDbmsWorker(ii, qSize);
            this.workerList.add(dbmsWorker);
            Thread worker = new Thread(workerGroup, dbmsWorker);
            worker.setName(String.format("dbsWorker-%02d.%02d", this.workers, ii+1));
            worker.setDaemon(true);
            this.threadList.add(worker);
        }
        for (Thread worker : this.threadList) {
            worker.start();
        }
    }

    public boolean add(Object object, int idx) {
        boolean offer = false;
        try {
            idx = idx % this.workers;
            offer = this.workerList.get(idx).add(object);
        }
        catch (Exception e) {
            log.error("QUEUE_DATA.add: Exception: {}, {}", object.toString(), e.getMessage());
        }
        return offer;
    }

    public void stop() {

    }

    public void report() {
        for (AbstractTsiCvimWorker worker : this.workerList) {
            worker.report();
        }
    }
}
