package ru.yandex.autotests.direct.fakebsproxy.service;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.UnknownFormatConversionException;
import java.util.stream.Collectors;

import javax.ws.rs.core.MediaType;

import org.springframework.stereotype.Service;

import ru.yandex.autotests.direct.fakebsproxy.beans.FakeBSProxyLogBean;
import ru.yandex.autotests.direct.fakebsproxy.beans.moderate.MagicQueueResponse;
import ru.yandex.autotests.direct.fakebsproxy.beans.moderate.ProcessMagicQueueParam;
import ru.yandex.autotests.direct.fakebsproxy.beans.moderate.PutRecordsParam;
import ru.yandex.autotests.direct.fakebsproxy.beans.moderate.PutRecordsResponse;
import ru.yandex.autotests.direct.fakebsproxy.beans.moderate.Request;
import ru.yandex.autotests.direct.fakebsproxy.beans.moderate.Result;
import ru.yandex.autotests.direct.fakebsproxy.beans.moderate.enums.ModerationMethodEnum;
import ru.yandex.autotests.direct.fakebsproxy.dao.FakeBSProxyLogBeanMongoHelper;
import ru.yandex.autotests.direct.fakebsproxy.service.utils.FakeBsProxyHttpClient;

/**
 * Created by buhter on 28/06/16.
 */
@Service
public class FakeBSProxyModerateService {
    private static final FakeBSProxyLogBeanMongoHelper MONGO_HELPER = new FakeBSProxyLogBeanMongoHelper();
    private static final String JSON_RPC_VERSION = "2.0";

    public String handlePutRecordsRequest(FakeBSProxyLogBean property, Request request) throws IOException {
        Long id;
        ArrayList<Result> results = new ArrayList<>();
        FakeBSProxyLogBean preloadedLogBean = null;

        List<PutRecordsParam> params = request.getDeserealizedParams();
        id = params.get(0).getCid();
        try {
            preloadedLogBean = MONGO_HELPER.getFakeBSProxyLogBeanById(ModerationMethodEnum.PUT_RECORDS + ":" + id);
        } catch (Exception e) {
        }
        //Если есть что-то в монге подготовленное для этого запроса
        if (preloadedLogBean != null) {
            //Если нет готового ответа
            if (preloadedLogBean.getResponseEntity() == null) {
                //Если есть урл для проксирования
                if (preloadedLogBean.getProxyURI() != null) {
                    try {
                        preloadedLogBean.setResponseEntity(
                                new FakeBsProxyHttpClient()
                                        .post(preloadedLogBean.getProxyURI(),
                                                request.toString(),
                                                property.getHeaders(),
                                                MediaType.APPLICATION_JSON)
                        );
                    } catch (IOException e) {
                        preloadedLogBean.setResponseEntity(e.getMessage());
                    }
                } else {
                    preloadedLogBean.setResponseEntity("No predefined putRecordsResponse or proxy url specified");
                }
            }
            //Если ничего нет, надо ответ сгенерить самим
        } else {
            for (PutRecordsParam param : params) {
                PutRecordsParam putRecordsParam = param;
                Result result = new Result()
                        .withErrors(null)
                        .withType(putRecordsParam.getType())
                        .withCid(putRecordsParam.getCid())
                        .withObjectId(new Random().nextLong())
                        .withStatusModerate("New")
                        .withStatusPostModerate("No");
                switch (putRecordsParam.getType()) {
                    case CALLOUT:
                        id = putRecordsParam.getCalloutId();
                        result
                                .withCid(null)
                                .withCalloutId(putRecordsParam.getCalloutId())
                                .withId(putRecordsParam.getCalloutId());
                        break;

                    case CAMPAIGN:
                        result
                                .withId(putRecordsParam.getCid());
                        break;
                    case PHRASES:
                        result
                                .withBid(putRecordsParam.getBid())
                                .withPid(putRecordsParam.getPid())
                                .withId(putRecordsParam.getPid());
                        break;
                    case BANNER:
                        result
                                .withBid(putRecordsParam.getBid())
                                .withPid(putRecordsParam.getPid())
                                .withId(putRecordsParam.getBid());
                        break;
                    case MOBILE_CONTENT:
                        id = putRecordsParam.getContentId();
                        result
                                .withCid(null)
                                .withContentId(putRecordsParam.getContentId())
                                .withId(putRecordsParam.getContentId());
                        break;
                    case IMAGE:
                    case IMAGE_AD:
                    case CANVAS:
                    case HTML5:
                    case VIDEO_ADDITION:
                    case DISPLAY_HREF:
                    case CONTACTINFO:
                    case SITELINKS_SET:
                        result
                                .withBid(putRecordsParam.getBid())
                                .withId(putRecordsParam.getBid());
                        break;
                    default:
                        throw new UnknownFormatConversionException("Unknown object type:" + putRecordsParam.getType());
                }
                results.add(result);
            }
            PutRecordsResponse putRecordsResponse = new PutRecordsResponse().withJsonrpc("2.0")
                    .withResult(results)
                    .withId(request.getId());

            preloadedLogBean = new FakeBSProxyLogBean().withResponseEntity(putRecordsResponse.toString());
        }
        preloadedLogBean
                .withObjectIds(ModerationMethodEnum.PUT_RECORDS + ":" + id)
                .withRequestTime(property.getRequestTime())
                .withRequestUUID(property.getRequestUUID())
                .withRequestEntity(request.toString());

        MONGO_HELPER.addMongoBean(preloadedLogBean);
        return preloadedLogBean.getResponseEntity();
    }

    public String handleGetDirectMagicQueueRequest(FakeBSProxyLogBean property, Request request) throws IOException {
        PutRecordsResponse putRecordsResponse = new PutRecordsResponse().withJsonrpc(JSON_RPC_VERSION)
                .withResult(new ArrayList<>())
                .withId(request.getId());
        return putRecordsResponse.toString();
    }

    public String handleProcessMagicQueueRequest(FakeBSProxyLogBean property, Request request) throws IOException {
        List<ProcessMagicQueueParam> params = ((ArrayList<ProcessMagicQueueParam>) request.getDeserealizedParams());
        List<Long> result = params.stream().map(ProcessMagicQueueParam::getId).collect(Collectors.toList());
        MagicQueueResponse magicQueueResponse = new MagicQueueResponse().withJsonrpc(JSON_RPC_VERSION)
                .withResult(result)
                .withId(request.getId());

        property.withObjectIds(
                ModerationMethodEnum.PROCESS_MAGIC_QUEUE + ":" + params.get(0).getCid())
                .withResponseEntity(magicQueueResponse.toString())
                .withRequestEntity(request.toString());

        MONGO_HELPER.addMongoBean(property);
        return property.getResponseEntity();
    }


}
