package ru.yandex.webmaster3.worker.turbo.export;

import java.util.UUID;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import ru.yandex.webmaster3.core.worker.task.PeriodicTaskState;
import ru.yandex.webmaster3.core.worker.task.PeriodicTaskType;
import ru.yandex.webmaster3.storage.turbo.dao.TurboCmntStatisticsYDao;
import ru.yandex.webmaster3.storage.util.yt.TableWriter;
import ru.yandex.webmaster3.storage.util.yt.YtColumn;
import ru.yandex.webmaster3.storage.util.yt.YtCypressService;
import ru.yandex.webmaster3.storage.util.yt.YtException;
import ru.yandex.webmaster3.storage.util.yt.YtNode;
import ru.yandex.webmaster3.storage.util.yt.YtNodeAttributes;
import ru.yandex.webmaster3.storage.util.yt.YtPath;
import ru.yandex.webmaster3.storage.util.yt.YtSchema;
import ru.yandex.webmaster3.storage.util.yt.YtService;
import ru.yandex.webmaster3.storage.util.yt.YtTableData;
import ru.yandex.webmaster3.worker.PeriodicTask;
import ru.yandex.webmaster3.worker.TaskSchedule;

/**
 * ishalaru
 * 13.08.2020
 **/
@Slf4j
@RequiredArgsConstructor(onConstructor_ = {@Autowired})
@Service
public class ExportTurboCmntUrlTask extends PeriodicTask<ExportTurboCmntUrlTask.State> {
    private final TurboCmntStatisticsYDao turboCmntStatisticsYDao;
    private final YtService ytService;
    @Value("${external.yt.service.hahn}://home/webmaster/users/ishalaru/turbo/export_cmnt_state")
    private YtPath tablePath;

    @Override
    public Result run(UUID runId) throws Exception {
        state = new State();
        YtTableData tableData = ytService.prepareTableData("export_cmnt_state", tableWriter ->
                turboCmntStatisticsYDao.streamReader(e -> writeBatch(e, tableWriter))
        );


        ytService
                .inTransaction(tablePath)
                .execute(cypressService -> uploadToYt(cypressService, tablePath, tableData));

        return Result.SUCCESS;
    }

    private boolean uploadToYt(YtCypressService cypressService, YtPath path,
                               YtTableData tableData)
            throws YtException {
        if (!cypressService.exists(path)) {
            YtNodeAttributes attributes = new YtNodeAttributes().setSchema(F.SCHEMA);
            cypressService.create(path, YtNode.NodeType.TABLE, true, attributes, true);
        }
        cypressService.writeTable(path, tableData, true);
        return true;
    }

    private void writeBatch(TurboCmntStatisticsYDao.TurboCmntStatistics value, TableWriter tw) throws YtException {
        F.DOMAIN.set(tw, value.getDomain());
        F.START_DATE.set(tw, value.getStartDate().toDate().getTime());
        F.URL.set(tw, value.getUrl());
        F.TITLE.set(tw, value.getTitle());
        F.ENABLE.set(tw, value.isEnable());
        tw.rowEnd();
        state.countReadRows++;
    }

    @Override
    public PeriodicTaskType getType() {
        return PeriodicTaskType.EXPORT_TURBO_CMNT_STATUS;
    }

    @Override
    public TaskSchedule getSchedule() {
        return TaskSchedule.never();
    }

    public class State implements PeriodicTaskState {
        int countReadRows;

        public int getCountReadRows() {
            return countReadRows;
        }
    }


    private interface F {
        YtSchema SCHEMA = new YtSchema();
        YtColumn<String> DOMAIN = SCHEMA.addColumn("domain", YtColumn.Type.STRING);
        YtColumn<String> URL = SCHEMA.addColumn("url", YtColumn.Type.STRING);
        YtColumn<Long> START_DATE = SCHEMA.addColumn("create_date", YtColumn.Type.INT_64);
        YtColumn<String> TITLE = SCHEMA.addColumn("title", YtColumn.Type.STRING);
        YtColumn<Boolean> ENABLE = SCHEMA.addColumn("enable", YtColumn.Type.BOOLEAN);
    }
}
