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

import java.util.Optional;
import java.util.UUID;

import lombok.RequiredArgsConstructor;
import org.joda.time.base.BaseDateTime;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import ru.yandex.webmaster3.core.util.json.JsonMapping;
import ru.yandex.webmaster3.core.worker.task.PeriodicTaskState;
import ru.yandex.webmaster3.core.worker.task.PeriodicTaskType;
import ru.yandex.webmaster3.core.worker.task.TaskResult;
import ru.yandex.webmaster3.storage.turbo.dao.adv.TurboAutoAdvYDao;
import ru.yandex.webmaster3.storage.util.yt.YtColumn;
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.worker.PeriodicTask;
import ru.yandex.webmaster3.worker.TaskSchedule;

/**
 * Created by Oleg Bazdyrev on 12/03/2021.
 */
@Service
@RequiredArgsConstructor(onConstructor_ = @Autowired)
public class ExportTurboAudoAdvTask extends PeriodicTask<PeriodicTaskState> {

    private interface F {
        YtSchema SCHEMA = new YtSchema();
        YtColumn<String> DOMAIN = SCHEMA.addColumn("Domain", YtColumn.Type.STRING);
        YtColumn<Object> INFO = SCHEMA.addColumn("Info", YtColumn.Type.ANY);
        YtColumn<String> STATUS = SCHEMA.addColumn("Status", YtColumn.Type.STRING);
        YtColumn<String> ADV_STATUS = SCHEMA.addColumn("AdvStatus", YtColumn.Type.STRING);
        YtColumn<Long> UPDATE_DATE = SCHEMA.addColumn("UpdateDate", YtColumn.Type.INT_64);
    }

    private final TurboAutoAdvYDao turboAutoAdvYDao;
    private final YtService ytService;

    @Value("${external.yt.service.hahn.root.default}/export/turbo/turbo-auto-adv")
    private YtPath tablePath;

    @Override
    public Result run(UUID runId) throws Exception {
        ytService.inTransaction(tablePath).execute(cypressService -> {
            YtNodeAttributes attributes = new YtNodeAttributes().setSchema(F.SCHEMA);
            cypressService.remove(tablePath, false, true);
            cypressService.create(tablePath, YtNode.NodeType.TABLE, true, attributes, true);
            cypressService.writeTable(tablePath, tw -> {
                turboAutoAdvYDao.forEach(record -> {
                    F.DOMAIN.set(tw, record.getDomain());
                    F.INFO.set(tw, JsonMapping.readTree(record.getInfo()));
                    F.STATUS.set(tw, Optional.ofNullable(record.getStatus()).map(Enum::name).orElse(null));
                    F.ADV_STATUS.set(tw, Optional.ofNullable(record.getAdvStatus()).map(Enum::name).orElse(null));
                    F.UPDATE_DATE.set(tw, Optional.ofNullable(record.getUpdateDate()).map(BaseDateTime::getMillis).orElse(null));
                    tw.rowEnd();
                });
            });
            return true;
        });
        return new Result(TaskResult.SUCCESS);
    }

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

    @Override
    public TaskSchedule getSchedule() {
        return TaskSchedule.startByCron("0 0 9 * * *");
    }
}
