package ru.yandex.autotests.directapi.apiclient.errors;

import java.util.List;

import org.hamcrest.Description;
import org.hamcrest.Factory;
import org.hamcrest.Matcher;
import org.hamcrest.TypeSafeDiagnosingMatcher;

import ru.yandex.autotests.directapi.apiclient.config.ApiLocale;

/**
 * Created by mariabye on 18.02.14.
 */
public class AxisErrorMatcher extends TypeSafeDiagnosingMatcher<AxisError> {
    private final AxisError expectedError;
    private final boolean isCodeInIgnoreList;

    public AxisErrorMatcher(AxisError expected) {
        this.expectedError = expected;
        this.isCodeInIgnoreList = false;
    }

    public AxisErrorMatcher(AxisError expected, List<String> ignoreDetailForCodes) {
        this.expectedError = expected;
        this.isCodeInIgnoreList = ignoreDetailForCodes != null
                && ignoreDetailForCodes.contains(expectedError.getErrorCode().toString());
    }

    @Override
    public void describeTo(Description description) {
        description.appendText(
                (isCodeInIgnoreList) ?
                        ("error comparing only codes " + expectedError.toString()) :
                        ("error with details " + expectedError.toString()));
    }

    protected boolean matchesSafely(AxisError item, Description mismatchDescription) {
        boolean matchesResult = true;
        //check error details
        if (expectedError.getDetails() == null || expectedError.getDetails().equals("")) {
            matchesResult = item.getDetails() == null || item.getDetails().equals("");
        } else if (item.getDetails() == null || item.getDetails().equals("")) {
            matchesResult = false;
        } else {
            matchesResult =
                    (item.getDetails()
                            .equals(expectedError.getDetails()) ||
                            item.getDetails()
                                    .equals(expectedError.getDetailsLocale().get(ApiLocale.EN.toString())) ||
                            item.getDetails()
                                    .equals(expectedError.getDetailsLocale().get(ApiLocale.RU.toString())));
        }

        //compare details only if error code not in ignore details list
        matchesResult = expectedError.getErrorCode().equals(item.getErrorCode()) &&
                (isCodeInIgnoreList || matchesResult && expectedError.getMessage().equals(item.getMessage()));
        if (!matchesResult) {
            mismatchDescription.appendText("\nerror was ");
            mismatchDescription.appendText(item.toString());
        }
        return matchesResult;
    }


    @Factory
    public static Matcher<AxisError> equalToIgnoreLocale(AxisError expectedError) {
        return new AxisErrorMatcher(expectedError);
    }

    @Factory
    public static Matcher<AxisError> equalToIgnoreLocale(AxisError expectedError, List<String> ignoreDetailForCodes) {
        return new AxisErrorMatcher(expectedError, ignoreDetailForCodes);
    }
}
