package ru.yandex.autotests.directapi.reports;

import org.junit.BeforeClass;
import org.junit.ClassRule;
import org.junit.Test;
import ru.yandex.aqua.annotations.project.Aqua;
import ru.yandex.autotests.direct.utils.config.DirectTestRunProperties;
import ru.yandex.autotests.directapi.apiclient.RequestHeader;
import ru.yandex.autotests.directapi.apiclient.config.ConnectionConfig;
import ru.yandex.autotests.directapi.apiclient.config.ProtocolType;
import ru.yandex.autotests.directapi.apiclient.errors.Api5Error;
import ru.yandex.autotests.directapi.apiclient.errors.Api5ErrorDetails;
import ru.yandex.autotests.directapi.apiclient.errors.Api5XmlError;
import ru.yandex.autotests.directapi.apiclient.errors.Api5XmlErrorMatcher;
import ru.yandex.autotests.directapi.apiclient.version5.BaseApiV5Request;
import ru.yandex.autotests.directapi.apiclient.version5.ReportsClient;
import ru.yandex.autotests.directapi.apiclient.version5.ServiceNames;
import ru.yandex.autotests.directapi.darkside.Logins;
import ru.yandex.autotests.directapi.darkside.connection.Semaphore;
import ru.yandex.autotests.directapi.model.api5.reports.ReportDefinitionMap;
import ru.yandex.autotests.directapi.model.api5.reports.ReportProcessingMode;
import ru.yandex.autotests.directapi.model.api5.reports.SelectionCriteriaMap;
import ru.yandex.autotests.directapi.rules.ApiSteps;
import ru.yandex.qatools.allure.annotations.Description;
import ru.yandex.qatools.allure.annotations.Features;
import ru.yandex.qatools.allure.annotations.Issue;
import ru.yandex.qatools.allure.annotations.Issues;
import ru.yandex.qatools.hazelcast.SemaphoreRule;

import static ru.yandex.autotests.irt.testutils.allure.TestSteps.assertThat;

/**
 * Created by onotole on 7/26/16.
 * https://st.yandex-team.ru/TESTIRT-9741
 */
@Aqua.Test
@Issues({
        @Issue("https://st.yandex-team.ru/DIRECT-59216"),
        @Issue("https://st.yandex-team.ru/DIRECT-59215")
})
@Description("Проверка валидации XSD")
@Features(ReportsFeatures.ONLINE_CUSTOM_REPORT)
public class InvalidXsdTest {
    public static final String LOGIN = ReportsLogins.CLIENT_FOR_RUB;

    @ClassRule
    public static ApiSteps api = new ApiSteps().as(Logins.LOGIN_SUPER).clientLogin(LOGIN);

    @ClassRule
    public static SemaphoreRule semaphore = Semaphore.getSemaphore();

    private static ReportsClient reportsClient;

    @BeforeClass
    public static void initClient() {
        BaseApiV5Request request = new BaseApiV5Request() {
            @Override
            public String getRequestAsString() {
                return (String) parameters;
            }

            @Override
            public ProtocolType getProtocolType() {
                return ProtocolType.XML;
            }
        };

        DirectTestRunProperties properties = DirectTestRunProperties.getInstance();
        ConnectionConfig connectionConfig = new ConnectionConfig(properties.getDirectAPIHost());
        RequestHeader requestHeader = new RequestHeader(LOGIN);
        reportsClient = new ReportsClient(connectionConfig, requestHeader, request);
    }

    @Test
    @Description("Ошибка в названии параметра, Pages вместо Page")
    public void testTypoInParamName() {
        String xml = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>" +
                "<ReportDefinition xmlns=\"http://api.direct.yandex.com/v5/reports\">" +
                "<SelectionCriteria/>" +
                "<FieldNames>CampaignId</FieldNames>" +
                // ошибка здесь
                "<Pages><Limit>10</Limit></Pages>" +
                "<ReportName>testReport</ReportName>" +
                "<ReportType>CUSTOM_REPORT</ReportType>" +
                "<DateRangeType>LAST_MONTH</DateRangeType>" +
                "<Format>TSV</Format>" +
                "<IncludeVAT>YES</IncludeVAT>" +
                "<IncludeDiscount>YES</IncludeDiscount>" +
                "</ReportDefinition>";

        Api5XmlError actualError = null;

        try {
            // онлайн, чтобы не кастить строку xml в ReportDefinition, что нужно для вызова apiReportsBuilder.pl
            reportsClient.invokeMethod(ServiceNames.REPORTS, LOGIN, null, xml, ReportProcessingMode.ONLINE, 5);
        } catch (Api5XmlError gotError) {
            actualError = gotError;
        }

        assertThat("получена правильная ошибка", actualError,
                new Api5XmlErrorMatcher(new Api5Error(8000,
                        Api5ErrorDetails.MISSING_REQUIRED_FIELD, "ReportDefinition", "ReportName").toXmlError()));
    }

    @Test
    @Description("Нет обязательного параметра DateRangeType")
    public void testMissingParam() {
        api.userSteps.reportsSteps().shouldGetReportsXmlErrorOn(LOGIN,
                new ReportDefinitionMap()
                        .withDefaultCustomReportWithUniqueReportName()
                        .withSelectionCriteria(new SelectionCriteriaMap())
                        .withDateRangeType(null),
                new Api5Error(8000,
                        Api5ErrorDetails.MISSING_REQUIRED_FIELD, "ReportDefinition", "DateRangeType"));
    }

    @Test
    @Description("Неизвестный параметр ProvideExtraData")
    public void testUnknownParam() {
        String xml = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>" +
                "<ReportDefinition xmlns=\"http://api.direct.yandex.com/v5/reports\">" +
                "<SelectionCriteria/>" +
                "<FieldNames>CampaignId</FieldNames>" +
                "<Page><Limit>10</Limit></Page>" +
                "<ReportName>testReport</ReportName>" +
                "<ReportType>CUSTOM_REPORT</ReportType>" +
                "<DateRangeType>LAST_MONTH</DateRangeType>" +
                "<Format>TSV</Format>" +
                "<IncludeVAT>YES</IncludeVAT>" +
                "<IncludeDiscount>YES</IncludeDiscount>" +
                "<ProvideExtraData/>" +
                "</ReportDefinition>";

        Api5XmlError actualError = null;

        try {
            reportsClient.invokeMethod(ServiceNames.REPORTS, LOGIN, null, xml);
        } catch (Api5XmlError gotError) {
            actualError = gotError;
        }

        assertThat("получена правильная ошибка", actualError,
                new Api5XmlErrorMatcher(new Api5Error(8000,
                        Api5ErrorDetails.INVALID_PARAMETER,
                        "http://api.direct.yandex.com/v5/reportsProvideExtraData").toXmlError()));
    }

}
