package ru.yandex.webmaster3.worker.download.urls;

import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

import lombok.RequiredArgsConstructor;
import org.joda.time.Instant;
import org.joda.time.format.DateTimeFormat;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import ru.yandex.webmaster3.core.codes.YandexHttpStatusUtil;
import ru.yandex.webmaster3.core.data.HttpCodeInfo;
import ru.yandex.webmaster3.core.metrics.Category;
import ru.yandex.webmaster3.core.worker.task.TaskResult;
import ru.yandex.webmaster3.storage.download.DownloadInfo;
import ru.yandex.webmaster3.storage.download.DownloadInfoYDao;
import ru.yandex.webmaster3.storage.download.DownloadStatus;
import ru.yandex.webmaster3.storage.indexing2.download.DownloadIndexingUrlSamplesTaskData;
import ru.yandex.webmaster3.storage.indexing2.download.IndexedUrlSampleCsvRow;
import ru.yandex.webmaster3.storage.indexing2.samples.IndexingSamplesService;
import ru.yandex.webmaster3.storage.indexing2.samples.data.IndexedUrlSample;
import ru.yandex.webmaster3.worker.ProcessingCountLimitedTask;
import ru.yandex.webmaster3.worker.download.DownloadRunnerService;

/**
 * Created by ifilippov5 on 28.02.17.
 */
@Category("indexing")
@RequiredArgsConstructor(onConstructor_ = @Autowired)
public class DownloadIndexingUrlSamplesTask extends ProcessingCountLimitedTask<DownloadIndexingUrlSamplesTaskData> {

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

    private final IndexingSamplesService indexingSamplesService;
    private final DownloadRunnerService downloadRunnerService;
    private final DownloadInfoYDao downloadInfoYDao;

    @Override
    public Result run(DownloadIndexingUrlSamplesTaskData data) {
        List<IndexedUrlSampleCsvRow> samples;
        try {
            samples = getSamples(data);
        } catch (Exception e) {
            log.error("Download task with hostId = {} and hash = {} terminate in status Internal Error through exception during get data",
                    data.getHostId(), data.getHash(), e);
            downloadInfoYDao.add(data.getHostId(), data.getHash(), DownloadInfo.error());
            throw e;
        }
        downloadRunnerService.run(data, samples);
        return new Result(TaskResult.SUCCESS);
    }

    private List<IndexedUrlSampleCsvRow> getSamples(DownloadIndexingUrlSamplesTaskData data) {
        List<IndexedUrlSample> samples = indexingSamplesService.getSamples(data.getHostId(), data.getFilters(), data.getOrderBy(),
                data.getOrderDirection(), 0, (int) indexingSamplesService.getSamplesCount(data.getHostId(), data.getFilters()));

        return samples.stream()
                .map(sample -> new IndexedUrlSampleCsvRow(
                        sample.getUrl(),
                        Optional.of(sample).map(IndexedUrlSample::getCurrentCode).map(HttpCodeInfo::getStatus).flatMap(YandexHttpStatusUtil::yandexHttpStatus2View).orElse("0"),
                        Optional.of(sample).map(IndexedUrlSample::getLastAccess).map(date -> date.toString(DateTimeFormat.forPattern("dd.MM.yyyy"))).orElse("")
                ))
                .collect(Collectors.toList());
    }

    @Override
    public Class<DownloadIndexingUrlSamplesTaskData> getDataClass() {
        return DownloadIndexingUrlSamplesTaskData.class;
    }
}
