package ru.yandex.webmaster3.storage.util.yt;

import com.fasterxml.jackson.databind.JsonNode;
import org.apache.commons.io.IOUtils;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.util.EntityUtils;
import org.jetbrains.annotations.NotNull;
import org.springframework.web.util.UriComponentsBuilder;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URI;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
 * Created by Oleg Bazdyrev on 07/11/2017.
 */
public class YtSelectRowsCommand extends YtCommandImpl.GetCommand<List<JsonNode>> {

    private final YtPath path;
    private final String where;
    private final String[] fields;

    public YtSelectRowsCommand(YtPath path, String where, String[] fields) {
        this.path = path;
        this.where = where;
        this.fields = fields;
    }

    @Override
    protected Object getYtParameters() {
        StringBuilder query = new StringBuilder();
        if (fields == null || fields.length == 0) {
            query.append("*");
        } else {
            query.append(Arrays.stream(fields).collect(Collectors.joining(",")));
        }
        query.append(" from [").append(path.toYtPath()).append("] where ");
        if (where != null) {
            query.append(where);
        }
        return new Params(query.toString());
    }

    @Override
    protected void addHeaders(HttpGet request) {
        super.addHeaders(request);
        request.setHeader("X-YT-Output-Format", "\"json\"");
    }

    @Override
    protected UriComponentsBuilder createUri(URI proxyUri) {
        return UriComponentsBuilder.fromUri(proxyUri).path(API_V3 + "/select_rows");
    }

    @Override
    protected YtResult<List<JsonNode>> onSuccess(YtStatus status, HttpResponse httpResponse) throws YtCommandException {
        HttpEntity entity = httpResponse.getEntity();
        if (entity == null) {
            return YtResult.createError(status, "Response is empty", null);
        }

        try (BufferedReader reader = new BufferedReader(new InputStreamReader(entity.getContent()))) {
            List<JsonNode> rows = new ArrayList<>();
            String line;
            while ((line = reader.readLine()) != null) {
                rows.add(YtService.OM.readTree(line));
            }
            return YtResult.createResult(status, rows);
        } catch (IOException e) {
            return YtResult.createError(status, "Unable to read response", e);
        }
    }

    @Override
    public boolean needHeavyProxy() {
        return true;
    }

    private static class Params {

        private final String query;

        private Params(String query) {
            this.query = query;
        }

        public String getQuery() {
            return query;
        }
    }
}
