package ru.yandex.webmaster3.viewer.http.turbo.sandbox;

import java.util.UUID;

import com.datastax.driver.core.utils.UUIDs;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;

import ru.yandex.autodoc.common.doc.annotation.Description;
import ru.yandex.webmaster3.core.WebmasterException;
import ru.yandex.webmaster3.core.http.ActionResponse;
import ru.yandex.webmaster3.core.http.ReadAction;
import ru.yandex.webmaster3.core.http.RequestQueryProperty;
import ru.yandex.webmaster3.core.http.WebmasterErrorResponse;
import ru.yandex.webmaster3.core.metrics.Category;
import ru.yandex.webmaster3.core.turbo.LoadTurboErrorContentTaskData;
import ru.yandex.webmaster3.core.turbo.model.feed.TurboFeedSettings;
import ru.yandex.webmaster3.core.util.WwwUtil;
import ru.yandex.webmaster3.core.worker.client.WorkerClient;
import ru.yandex.webmaster3.storage.util.ydb.exception.WebmasterYdbException;
import ru.yandex.webmaster3.storage.download.DownloadStatus;
import ru.yandex.webmaster3.storage.turbo.dao.TurboDownloadTask;
import ru.yandex.webmaster3.storage.turbo.dao.TurboDownloadTasksYDao;
import ru.yandex.webmaster3.storage.turbo.service.TurboFeedsService;
import ru.yandex.webmaster3.viewer.http.AbstractUserVerifiedHostAction;
import ru.yandex.webmaster3.viewer.http.AbstractUserVerifiedHostRequest;
import ru.yandex.webmaster3.viewer.http.turbo.sandbox.FindTurboErrorContentAction.Request;
import ru.yandex.webmaster3.viewer.http.turbo.sandbox.FindTurboErrorContentAction.Response;

/**
 * Created by Oleg Bazdyrev on 19/04/2018.
 */
@ReadAction
@Category("turbo")
@Description("Получение текста item-а или всего фида с переданной ошибкой")
@RequiredArgsConstructor(onConstructor_ = @Autowired)
public class FindTurboErrorContentAction extends AbstractUserVerifiedHostAction<Request, Response> {

    private final TurboDownloadTasksYDao turboDownloadTaskYDao;
    private final TurboFeedsService turboFeedsService;
    private final WorkerClient workerClient;

    @Override
    public Response process(Request request) {
        UUID taskId = UUIDs.timeBased();
        try {
            String domain = WwwUtil.cutWWWAndM(request.getHostId());
            TurboFeedSettings feedSettings = turboFeedsService.getFeed(domain, request.feedUrl);
            if (feedSettings == null) {
                throw new WebmasterException("Non-existant feed url",
                        new WebmasterErrorResponse.IllegalParameterValueResponse(getClass(), "feedUrl", request.feedUrl));
            }
            turboDownloadTaskYDao.insertTask(
                    new TurboDownloadTask(taskId, feedSettings.getType(), DownloadStatus.IN_PROGRESS, null, null));
            // запускаем таску, которая будет реально скачивать
            if (!workerClient.checkedEnqueueTask(new LoadTurboErrorContentTaskData(taskId, request.getHostId(),
                    request.feedUrl, request.itemUrl, feedSettings.getType()))) {
                throw new WebmasterException("Unable to send task to worker",
                        new WebmasterErrorResponse.WorkerErrorResponse(getClass(), null));
            }

        } catch (WebmasterYdbException e) {
            throw new WebmasterException("Cassandra error",
                    new WebmasterErrorResponse.YDBErrorResponse(getClass(), e), e);
        }
        return new Response(taskId);
    }

    public static final class Request extends AbstractUserVerifiedHostRequest {

        private String feedUrl;
        private String itemUrl;

        @RequestQueryProperty(required = true)
        @Description("URL фида с ошибкой")
        public void setFeedUrl(String feedUrl) {
            this.feedUrl = feedUrl;
        }

        @RequestQueryProperty(required = true)
        @Description("URL требуемого айтема")
        public void setItemUrl(String itemUrl) {
            this.itemUrl = itemUrl;
        }
    }

    public static final class Response implements ActionResponse.NormalResponse {

        private final UUID taskId;

        public Response(UUID taskId) {
            this.taskId = taskId;
        }

        @Description("Идентификатор задачи с результатов поиска текста ошибки")
        public UUID getTaskId() {
            return taskId;
        }
    }

}
