package ru.yandex.webmaster3.viewer.http.download;

import com.google.common.hash.Hasher;
import com.google.common.hash.Hashing;

import ru.yandex.webmaster3.core.metrics.Category;
import ru.yandex.webmaster3.storage.AbstractFilter;
import ru.yandex.webmaster3.storage.download.common.MdsExportDescriptor;
import ru.yandex.webmaster3.storage.download.common.MdsExportTaskData;
import ru.yandex.webmaster3.viewer.http.SiteTreeNodeAware;

import java.nio.charset.StandardCharsets;

/**
 * @author avhaliullin
 */
@Category("dowmload")
public abstract class DownloadAction2<T extends DownloadRequest<?, ?>> extends DownloadAction<T> {
    @Override
    protected MdsExportTaskData getTaskData(T request, long hash) {
        return new MdsExportTaskData(
                request.getHostId(),
                request.getExportFormat(),
                generateFileName(request, hash),
                hash,
                makeRequest(request)
        );
    }

    protected abstract MdsExportDescriptor makeRequest(T request);

    protected long getHash(T request) {
        Hasher h = Hashing.sha256().newHasher();
        h.putInt(request.getExportFormat().ordinal());
        if (request instanceof SiteTreeNodeAware) {
            SiteTreeNodeAware stn = (SiteTreeNodeAware) request;
            if (stn.getNodeId() != null) {
                h.putBytes("node:".getBytes())
                        .putLong(stn.getNodeId());
            }
        }
        if (request.getParameterFilters() != null) {
            for (AbstractFilter f : request.getParameterFilters()) {
                h.putBytes("f:".getBytes())
                        .putInt(f.getIndicator().ordinal())
                        .putInt(f.getOperation().ordinal())
                        .putString(f.getValue(), StandardCharsets.UTF_8);
                if (f.getLogicalOperator() != null) {
                    h.putInt(f.getLogicalOperator().ordinal());
                }
            }
        }
        customizeHash(h, request);
        return h.hash().asLong();
    }

    protected void customizeHash(Hasher h, T request) {}
}
