package ru.yandex.wmconsole.servantlet.sitemaps;

import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import java.util.zip.GZIPInputStream;

import org.apache.commons.io.IOUtils;
import org.apache.commons.io.input.BoundedInputStream;
import org.apache.commons.io.input.CountingInputStream;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import ru.yandex.common.framework.core.RemoteFile;
import ru.yandex.common.framework.core.ServRequest;
import ru.yandex.wmconsole.service.error.WMCUserProblem;
import ru.yandex.wmconsole.viewer.sitemap.SitemapService2;
import ru.yandex.wmtools.common.error.UserException;
import ru.yandex.wmtools.common.error.UserProblem;
import ru.yandex.wmtools.common.util.http.HttpUtils;

/**
 * Поставщик данных из HttpEntity
 */
public class SitemapRemoteFileDataProvider implements SitemapDataProvider {
    private static final Logger log = LoggerFactory.getLogger(SitemapRemoteFileDataProvider.class);

    private static final String SITEMAP_REMOTE_FILE_NAME = "sitemap";

    private final ServRequest request;

    public SitemapRemoteFileDataProvider(ServRequest request) {
        this.request = request;
    }

    @Override
    public void provideData(SitemapRequestBuilder builder) throws UserException {
        // Пытаемся найти содержимое среди multipart-файлов
        log.debug("Getting sitemap from remote file...");
        final List<RemoteFile> files = request.getRemoteFiles();
        for (RemoteFile rf : files) {
            if (SITEMAP_REMOTE_FILE_NAME.equals(rf.getName())) {
                InputStream is = null;
                try {
                    is = rf.getInputStream();
                    if (HttpUtils.isGzipped(rf.getContentType(), null)) {
                        is = new GZIPInputStream(is);
                    }
                    BoundedInputStream boundedInputStream = new BoundedInputStream(is,
                            SitemapService2.MAX_SITEMAP_LEGHT + 16);
                    CountingInputStream countingInputStream = new CountingInputStream(boundedInputStream);
                    IOUtils.copy(is, builder.getStream());
                    if (countingInputStream.getByteCount() > SitemapService2.MAX_SITEMAP_LEGHT) {
                        throw new UserException(UserProblem.SITEMAP_TOO_LONG, "Sitemap file size limit exceeded");
                    }
                    return;
                } catch (IOException e) {
                    log.error("Unable to read sitemap", e);
                    throw new UserException(WMCUserProblem.SITEMAP_ACCESS_ERROR, "Failed to load sitemap from remote file", e);
                } finally {
                    IOUtils.closeQuietly(is);
                }
            }
        }
        throw new UserException(
                UserProblem.REQUIRED_PARAM_MISSED,
                "required 'sitemap' or 'url' or 'sitemap' multipart file content");
    }
}
