package ru.yandex.autotests.directintapi.bstransport.matchers.images;

import org.hamcrest.BaseMatcher;
import org.hamcrest.Description;
import org.hamcrest.Matcher;

import ru.yandex.autotests.direct.utils.matchers.BeanCompareStrategy;
import ru.yandex.autotests.direct.utils.matchers.BeanEquals;
import ru.yandex.autotests.directapi.beans.images.ImageFormat;
import ru.yandex.autotests.directapi.darkside.model.bslogs.clientdata.Image;
import ru.yandex.autotests.directapi.darkside.model.bslogs.clientdata.Images;
import ru.yandex.autotests.directapi.darkside.model.bslogs.clientdata.SmartCenter;

import static org.hamcrest.Matchers.greaterThan;
import static org.hamcrest.Matchers.greaterThanOrEqualTo;
import static org.hamcrest.Matchers.nullValue;
import static org.hamcrest.Matchers.startsWith;

public class BannerRegularImagesMatcher extends BaseMatcher<Images> {

    private static final String URL_BEGIN = "//";
    private final Matcher<Images> matcher;

    private BannerRegularImagesMatcher(boolean dontSendExtraImageFormats) {
        matcher = buildImagesMatcher(dontSendExtraImageFormats);
    }

    public static BannerRegularImagesMatcher isValid() {
        return new BannerRegularImagesMatcher(false);
    }

    public static BannerRegularImagesMatcher isValid(boolean dontSendExtraImageFormats) {
        return new BannerRegularImagesMatcher(dontSendExtraImageFormats);
    }

    //4:3 format
    private static Matcher<Images> buildImagesMatcher(boolean dontSendExtraImageFormats) {
        Images images = new Images();

        BeanEquals<Image> matcherX80 = BeanEquals.beanEquals(
                new Image().withWidth(Integer.parseInt(ImageFormat.X_80.getWidth()))
        ).accordingStrategy(new BeanCompareStrategy()
                .putFieldMatcher(Image.SMART_CENTER, BeanEquals.beanEquals(new SmartCenter())
                        .accordingStrategy(
                                new BeanCompareStrategy()
                                        .putFieldMatcher(SmartCenter.WIDTH, greaterThanOrEqualTo(0))
                                        .putFieldMatcher(SmartCenter.HEIGHT, greaterThanOrEqualTo(0))
                                        .putFieldMatcher(SmartCenter.X, greaterThanOrEqualTo(0))
                                        .putFieldMatcher(SmartCenter.Y, greaterThanOrEqualTo(0))))
                .putFieldMatcher(Image.URL.toLowerCase(), startsWith(URL_BEGIN))
                .putFieldMatcher(Image.HEIGHT, greaterThan(0)));

        BeanEquals<Image> matcherX90 = BeanEquals.beanEquals(
                new Image().withWidth(Integer.parseInt(ImageFormat.X_90.getWidth()))
        ).accordingStrategy(new BeanCompareStrategy()
                .putFieldMatcher(Image.SMART_CENTER, BeanEquals.beanEquals(new SmartCenter())
                        .accordingStrategy(
                                new BeanCompareStrategy()
                                        .putFieldMatcher(SmartCenter.WIDTH, greaterThanOrEqualTo(0))
                                        .putFieldMatcher(SmartCenter.HEIGHT, greaterThanOrEqualTo(0))
                                        .putFieldMatcher(SmartCenter.X, greaterThanOrEqualTo(0))
                                        .putFieldMatcher(SmartCenter.Y, greaterThanOrEqualTo(0))))
                .putFieldMatcher(Image.URL.toLowerCase(), startsWith(URL_BEGIN))
                .putFieldMatcher(Image.HEIGHT, greaterThan(0)));

        BeanEquals<Image> matcherX150 = BeanEquals.beanEquals(
                new Image().withWidth(Integer.parseInt(ImageFormat.X_150.getWidth()))
        ).accordingStrategy(new BeanCompareStrategy()
                .putFieldMatcher(Image.SMART_CENTER, BeanEquals.beanEquals(new SmartCenter())
                        .accordingStrategy(
                                new BeanCompareStrategy()
                                        .putFieldMatcher(SmartCenter.WIDTH, greaterThanOrEqualTo(0))
                                        .putFieldMatcher(SmartCenter.HEIGHT, greaterThanOrEqualTo(0))
                                        .putFieldMatcher(SmartCenter.X, greaterThanOrEqualTo(0))
                                        .putFieldMatcher(SmartCenter.Y, greaterThanOrEqualTo(0))))
                .putFieldMatcher(Image.URL.toLowerCase(), startsWith(URL_BEGIN))
                .putFieldMatcher(Image.HEIGHT, greaterThan(0)));

        BeanEquals<Image> matcherX160 = BeanEquals.beanEquals(
                new Image().withWidth(Integer.parseInt(ImageFormat.X_160.getWidth()))
        ).accordingStrategy(new BeanCompareStrategy()
                .putFieldMatcher(Image.SMART_CENTER, BeanEquals.beanEquals(new SmartCenter())
                        .accordingStrategy(
                                new BeanCompareStrategy()
                                        .putFieldMatcher(SmartCenter.WIDTH, greaterThanOrEqualTo(0))
                                        .putFieldMatcher(SmartCenter.HEIGHT, greaterThanOrEqualTo(0))
                                        .putFieldMatcher(SmartCenter.X, greaterThanOrEqualTo(0))
                                        .putFieldMatcher(SmartCenter.Y, greaterThanOrEqualTo(0))))
                .putFieldMatcher(Image.URL.toLowerCase(), startsWith(URL_BEGIN))
                .putFieldMatcher(Image.HEIGHT, greaterThan(0)));

        BeanEquals<Image> matcherX180 = BeanEquals.beanEquals(
                new Image().withWidth(Integer.parseInt(ImageFormat.X_180.getWidth()))
        ).accordingStrategy(new BeanCompareStrategy()
                .putFieldMatcher(Image.SMART_CENTER, BeanEquals.beanEquals(new SmartCenter())
                        .accordingStrategy(
                                new BeanCompareStrategy()
                                        .putFieldMatcher(SmartCenter.WIDTH, greaterThanOrEqualTo(0))
                                        .putFieldMatcher(SmartCenter.HEIGHT, greaterThanOrEqualTo(0))
                                        .putFieldMatcher(SmartCenter.X, greaterThanOrEqualTo(0))
                                        .putFieldMatcher(SmartCenter.Y, greaterThanOrEqualTo(0))))
                .putFieldMatcher(Image.URL.toLowerCase(), startsWith(URL_BEGIN))
                .putFieldMatcher(Image.HEIGHT, greaterThan(0)));

        BeanEquals<Image> matcherX300 = BeanEquals.beanEquals(
                new Image().withWidth(Integer.parseInt(ImageFormat.X_300.getWidth()))
        ).accordingStrategy(new BeanCompareStrategy()
                .putFieldMatcher(Image.SMART_CENTER, BeanEquals.beanEquals(new SmartCenter())
                        .accordingStrategy(
                                new BeanCompareStrategy()
                                        .putFieldMatcher(SmartCenter.WIDTH, greaterThanOrEqualTo(0))
                                        .putFieldMatcher(SmartCenter.HEIGHT, greaterThanOrEqualTo(0))
                                        .putFieldMatcher(SmartCenter.X, greaterThanOrEqualTo(0))
                                        .putFieldMatcher(SmartCenter.Y, greaterThanOrEqualTo(0))))
                .putFieldMatcher(Image.URL.toLowerCase(), startsWith(URL_BEGIN))
                .putFieldMatcher(Image.HEIGHT, greaterThan(0)));

        BeanEquals<Image> matcherX450 = BeanEquals.beanEquals(
                new Image().withWidth(Integer.parseInt(ImageFormat.X_450.getWidth()))
        ).accordingStrategy(new BeanCompareStrategy()
                .putFieldMatcher(Image.SMART_CENTER, BeanEquals.beanEquals(new SmartCenter())
                        .accordingStrategy(
                                new BeanCompareStrategy()
                                        .putFieldMatcher(SmartCenter.WIDTH, greaterThanOrEqualTo(0))
                                        .putFieldMatcher(SmartCenter.HEIGHT, greaterThanOrEqualTo(0))
                                        .putFieldMatcher(SmartCenter.X, greaterThanOrEqualTo(0))
                                        .putFieldMatcher(SmartCenter.Y, greaterThanOrEqualTo(0))))
                .putFieldMatcher(Image.URL.toLowerCase(), startsWith(URL_BEGIN))
                .putFieldMatcher(Image.HEIGHT, greaterThan(0)));

        BeanEquals<Image> matcherY65 = BeanEquals.beanEquals(
                new Image().withHeight(Integer.parseInt(ImageFormat.Y_65.getHeight()))
        ).accordingStrategy(new BeanCompareStrategy()
                .putFieldMatcher(Image.SMART_CENTER, BeanEquals.beanEquals(new SmartCenter())
                        .accordingStrategy(
                                new BeanCompareStrategy()
                                        .putFieldMatcher(SmartCenter.WIDTH, greaterThanOrEqualTo(0))
                                        .putFieldMatcher(SmartCenter.HEIGHT, greaterThanOrEqualTo(0))
                                        .putFieldMatcher(SmartCenter.X, greaterThanOrEqualTo(0))
                                        .putFieldMatcher(SmartCenter.Y, greaterThanOrEqualTo(0))))
                .putFieldMatcher(Image.URL.toLowerCase(), startsWith(URL_BEGIN))
                .putFieldMatcher(Image.WIDTH, greaterThan(0)));

        BeanEquals<Image> matcherY80 = BeanEquals.beanEquals(
                new Image().withHeight(Integer.parseInt(ImageFormat.Y_80.getHeight()))
        ).accordingStrategy(new BeanCompareStrategy()
                .putFieldMatcher(Image.SMART_CENTER, BeanEquals.beanEquals(new SmartCenter())
                        .accordingStrategy(
                                new BeanCompareStrategy()
                                        .putFieldMatcher(SmartCenter.WIDTH, greaterThanOrEqualTo(0))
                                        .putFieldMatcher(SmartCenter.HEIGHT, greaterThanOrEqualTo(0))
                                        .putFieldMatcher(SmartCenter.X, greaterThanOrEqualTo(0))
                                        .putFieldMatcher(SmartCenter.Y, greaterThanOrEqualTo(0))))
                .putFieldMatcher(Image.URL.toLowerCase(), startsWith(URL_BEGIN))
                .putFieldMatcher(Image.WIDTH, greaterThan(0)));
        BeanEquals<Image> matcherY90 = BeanEquals.beanEquals(
                new Image().withHeight(Integer.parseInt(ImageFormat.Y_90.getHeight()))
        ).accordingStrategy(new BeanCompareStrategy()
                .putFieldMatcher(Image.SMART_CENTER, BeanEquals.beanEquals(new SmartCenter())
                        .accordingStrategy(
                                new BeanCompareStrategy()
                                        .putFieldMatcher(SmartCenter.WIDTH, greaterThanOrEqualTo(0))
                                        .putFieldMatcher(SmartCenter.HEIGHT, greaterThanOrEqualTo(0))
                                        .putFieldMatcher(SmartCenter.X, greaterThanOrEqualTo(0))
                                        .putFieldMatcher(SmartCenter.Y, greaterThanOrEqualTo(0))))
                .putFieldMatcher(Image.URL.toLowerCase(), startsWith(URL_BEGIN))
                .putFieldMatcher(Image.WIDTH, greaterThan(0)));
        BeanEquals<Image> matcherY110 = BeanEquals.beanEquals(
                new Image().withHeight(Integer.parseInt(ImageFormat.Y_110.getHeight()))
        ).accordingStrategy(new BeanCompareStrategy()
                .putFieldMatcher(Image.SMART_CENTER, BeanEquals.beanEquals(new SmartCenter())
                        .accordingStrategy(
                                new BeanCompareStrategy()
                                        .putFieldMatcher(SmartCenter.WIDTH, greaterThanOrEqualTo(0))
                                        .putFieldMatcher(SmartCenter.HEIGHT, greaterThanOrEqualTo(0))
                                        .putFieldMatcher(SmartCenter.X, greaterThanOrEqualTo(0))
                                        .putFieldMatcher(SmartCenter.Y, greaterThanOrEqualTo(0))))
                .putFieldMatcher(Image.URL.toLowerCase(), startsWith(URL_BEGIN))
                .putFieldMatcher(Image.WIDTH, greaterThan(0)));
        BeanEquals<Image> matcherY129 = BeanEquals.beanEquals(
                new Image().withHeight(Integer.parseInt(ImageFormat.Y_129.getHeight()))
        ).accordingStrategy(new BeanCompareStrategy()
                .putFieldMatcher(Image.SMART_CENTER, BeanEquals.beanEquals(new SmartCenter())
                        .accordingStrategy(
                                new BeanCompareStrategy()
                                        .putFieldMatcher(SmartCenter.WIDTH, greaterThanOrEqualTo(0))
                                        .putFieldMatcher(SmartCenter.HEIGHT, greaterThanOrEqualTo(0))
                                        .putFieldMatcher(SmartCenter.X, greaterThanOrEqualTo(0))
                                        .putFieldMatcher(SmartCenter.Y, greaterThanOrEqualTo(0))))
                .putFieldMatcher(Image.URL.toLowerCase(), startsWith(URL_BEGIN))
                .putFieldMatcher(Image.WIDTH, greaterThan(0)));
        BeanEquals<Image> matcherY150 = BeanEquals.beanEquals(
                new Image().withHeight(Integer.parseInt(ImageFormat.Y_150.getHeight()))
        ).accordingStrategy(new BeanCompareStrategy()
                .putFieldMatcher(Image.SMART_CENTER, BeanEquals.beanEquals(new SmartCenter())
                        .accordingStrategy(
                                new BeanCompareStrategy()
                                        .putFieldMatcher(SmartCenter.WIDTH, greaterThanOrEqualTo(0))
                                        .putFieldMatcher(SmartCenter.HEIGHT, greaterThanOrEqualTo(0))
                                        .putFieldMatcher(SmartCenter.X, greaterThanOrEqualTo(0))
                                        .putFieldMatcher(SmartCenter.Y, greaterThanOrEqualTo(0))))
                .putFieldMatcher(Image.URL.toLowerCase(), startsWith(URL_BEGIN))
                .putFieldMatcher(Image.WIDTH, greaterThan(0)));
        BeanEquals<Image> matcherY160 = BeanEquals.beanEquals(
                new Image().withHeight(Integer.parseInt(ImageFormat.Y_160.getHeight()))
        ).accordingStrategy(new BeanCompareStrategy()
                .putFieldMatcher(Image.SMART_CENTER, BeanEquals.beanEquals(new SmartCenter())
                        .accordingStrategy(
                                new BeanCompareStrategy()
                                        .putFieldMatcher(SmartCenter.WIDTH, greaterThanOrEqualTo(0))
                                        .putFieldMatcher(SmartCenter.HEIGHT, greaterThanOrEqualTo(0))
                                        .putFieldMatcher(SmartCenter.X, greaterThanOrEqualTo(0))
                                        .putFieldMatcher(SmartCenter.Y, greaterThanOrEqualTo(0))))
                .putFieldMatcher(Image.URL.toLowerCase(), startsWith(URL_BEGIN))
                .putFieldMatcher(Image.WIDTH, greaterThan(0)));
        BeanEquals<Image> matcherY180 = BeanEquals.beanEquals(
                new Image().withHeight(Integer.parseInt(ImageFormat.Y_180.getHeight()))
        ).accordingStrategy(new BeanCompareStrategy()
                .putFieldMatcher(Image.SMART_CENTER, BeanEquals.beanEquals(new SmartCenter())
                        .accordingStrategy(
                                new BeanCompareStrategy()
                                        .putFieldMatcher(SmartCenter.WIDTH, greaterThanOrEqualTo(0))
                                        .putFieldMatcher(SmartCenter.HEIGHT, greaterThanOrEqualTo(0))
                                        .putFieldMatcher(SmartCenter.X, greaterThanOrEqualTo(0))
                                        .putFieldMatcher(SmartCenter.Y, greaterThanOrEqualTo(0))))
                .putFieldMatcher(Image.URL.toLowerCase(), startsWith(URL_BEGIN))
                .putFieldMatcher(Image.WIDTH, greaterThan(0)));
        BeanEquals<Image> matcherY300 = BeanEquals.beanEquals(
                new Image().withHeight(Integer.parseInt(ImageFormat.Y_300.getHeight()))
        ).accordingStrategy(new BeanCompareStrategy()
                .putFieldMatcher(Image.SMART_CENTER, BeanEquals.beanEquals(new SmartCenter())
                        .accordingStrategy(
                                new BeanCompareStrategy()
                                        .putFieldMatcher(SmartCenter.WIDTH, greaterThanOrEqualTo(0))
                                        .putFieldMatcher(SmartCenter.HEIGHT, greaterThanOrEqualTo(0))
                                        .putFieldMatcher(SmartCenter.X, greaterThanOrEqualTo(0))
                                        .putFieldMatcher(SmartCenter.Y, greaterThanOrEqualTo(0))))
                .putFieldMatcher(Image.URL.toLowerCase(), startsWith(URL_BEGIN))
                .putFieldMatcher(Image.WIDTH, greaterThan(0)));

        BeanEquals<Image> matcherY450 = BeanEquals.beanEquals(
                new Image().withHeight(Integer.parseInt(ImageFormat.Y_450.getHeight()))
        ).accordingStrategy(new BeanCompareStrategy()
                .putFieldMatcher(Image.SMART_CENTER, BeanEquals.beanEquals(new SmartCenter())
                        .accordingStrategy(
                                new BeanCompareStrategy()
                                        .putFieldMatcher(SmartCenter.WIDTH, greaterThanOrEqualTo(0))
                                        .putFieldMatcher(SmartCenter.HEIGHT, greaterThanOrEqualTo(0))
                                        .putFieldMatcher(SmartCenter.X, greaterThanOrEqualTo(0))
                                        .putFieldMatcher(SmartCenter.Y, greaterThanOrEqualTo(0))))
                .putFieldMatcher(Image.URL.toLowerCase(), startsWith(URL_BEGIN))
                .putFieldMatcher(Image.WIDTH, greaterThan(0)));

        BeanCompareStrategy strategy = new BeanCompareStrategy();
        strategy.putFieldMatcher("x90", matcherX90);
        strategy.putFieldMatcher("x150", matcherX150);
        strategy.putFieldMatcher("x180", matcherX180);
        strategy.putFieldMatcher("x300", matcherX300);
        strategy.putFieldMatcher("x450", matcherX450);
        strategy.putFieldMatcher("y90", matcherY90);
        strategy.putFieldMatcher("y150", matcherY150);
        strategy.putFieldMatcher("y180", matcherY180);
        strategy.putFieldMatcher("y300", matcherY300);
        strategy.putFieldMatcher("y450", matcherY450);

        if (dontSendExtraImageFormats) {
            strategy.putFieldMatcher("x80", nullValue());
            strategy.putFieldMatcher("x160", nullValue());
            strategy.putFieldMatcher("y65", nullValue());
            strategy.putFieldMatcher("y80", nullValue());
            strategy.putFieldMatcher("y110", nullValue());
            strategy.putFieldMatcher("y129", nullValue());
            strategy.putFieldMatcher("y160", nullValue());
        } else {
            strategy.putFieldMatcher("x80", matcherX80);
            strategy.putFieldMatcher("x160", matcherX160);
            strategy.putFieldMatcher("y65", matcherY65);
            strategy.putFieldMatcher("y80", matcherY80);
            strategy.putFieldMatcher("y110", matcherY110);
            strategy.putFieldMatcher("y129", matcherY129);
            strategy.putFieldMatcher("y160", matcherY160);

        }

        // wide formats
        strategy.putFieldMatcher("wx150", nullValue());
        strategy.putFieldMatcher("wx300", nullValue());
        strategy.putFieldMatcher("wx600", nullValue());
        strategy.putFieldMatcher("wx1080", nullValue());
        strategy.putFieldMatcher("wy150", nullValue());
        strategy.putFieldMatcher("wy300", nullValue());

        return BeanEquals
                .beanEquals(images)
                .accordingStrategy(strategy);
    }

    @Override
    public boolean matches(Object images) {
        return matcher.matches(images);
    }

    @Override
    public void describeTo(Description description) {
        matcher.describeTo(description);
    }

    @Override
    public void describeMismatch(Object item, Description description) {
        matcher.describeMismatch(item, description);
    }

}
