package ru.yandex.webmaster3.core.semantic.review_business.auto.model.ugc.impl.wrapper;

import com.google.common.base.Preconditions;
import ru.yandex.webmaster3.core.semantic.review_business.auto.model.AutoModeration;
import ru.yandex.webmaster3.core.semantic.review_business.auto.model.HProduct;
import ru.yandex.webmaster3.core.semantic.review_business.auto.model.impl.wrapper.BaseAutoReviewWrapper;
import ru.yandex.webmaster3.core.semantic.review_business.auto.model.ugc.UgcAutoReview;
import ru.yandex.webmaster3.core.semantic.review_business.model.Author;
import ru.yandex.webmaster3.core.semantic.review_business.model.UserIdentity;

import java.util.*;

/**
 * User: Evgeny Zhoga (ezhoga@yandex-team.ru)
 * Date: 15/10/12
 * Time: 7:03 PM
 */
public class UgcAutoReviewWrapper extends UgcAutoReview {
    private final UgcAutoReview review;
    private final BaseAutoReviewWrapper baseReview;

    public static UgcAutoReviewWrapper newUgcAutoReview() {
        return EMPTY_UGC_AUTO_REVIEW_WRAPPER;
    }

    public UgcAutoReviewWrapper(UgcAutoReview review) {
        this(review, new BaseAutoReviewWrapper(review));
    }

    public UgcAutoReviewWrapper(UgcAutoReview review, BaseAutoReviewWrapper baseReview) {
        Preconditions.checkNotNull(review, "Unable to wrap null UgcAutoReview!");

        this.review = review;
        this.baseReview = baseReview;
    }

    @Override
    public String getLanguage() {
        return baseReview.getLanguage();
    }

    public UgcAutoReviewWrapper setLanguage(final String language) {
        return wrapBaseReview(baseReview.setLanguage(language));
    }

    @Override
    public String getSummary() {
        return baseReview.getSummary();
    }

    public UgcAutoReviewWrapper setSummary(final String summary) {
        return wrapBaseReview(baseReview.setSummary(summary));
    }

    @Override
    public Date getWatchTime() {
        return baseReview.getWatchTime();
    }

    public UgcAutoReviewWrapper setWatchTime(final Date watchTime) {
        return wrapBaseReview(baseReview.setWatchTime(watchTime));
    }

    @Override
    public HProduct getItem() {
        return baseReview.getItem();
    }

    @Override
    public Collection<String> getPhotos() {
        return baseReview.getPhotos();
    }

    public UgcAutoReviewWrapper addPhotos(final String... photos) {
        return wrapBaseReview(baseReview.addPhotos(photos));
    }

    public UgcAutoReviewWrapper addPhotos(final Collection<String> photos) {
        return wrapBaseReview(baseReview.addPhotos(photos));
    }

    public UgcAutoReviewWrapper setPhotos(final String... photos) {
        return wrapBaseReview(baseReview.setPhotos(photos));
    }

    public UgcAutoReviewWrapper setPhotos(final Collection<String> photos) {
        return wrapBaseReview(baseReview.setPhotos(photos));
    }

    public UgcAutoReviewWrapper setItem(final HProduct item) {
        return wrapBaseReview(baseReview.setItem(item));
    }

    @Override
    public Collection<String> getPros() {
        return baseReview.getPros();
    }

    public UgcAutoReviewWrapper addPros(final String... pros) {
        return wrapBaseReview(baseReview.addPros(pros));
    }

    @SuppressWarnings("unchecked")
    public UgcAutoReviewWrapper addPros(final Collection<String> pros) {
        return wrapBaseReview(baseReview.addPros(pros));
    }

    public UgcAutoReviewWrapper setPros(final String... pros) {
        return wrapBaseReview(baseReview.setPros(pros));
    }

    public UgcAutoReviewWrapper setPros(final Collection<String> pros) {
        return wrapBaseReview(baseReview.setPros(pros));
    }

    @Override
    public Collection<String> getContras() {
        return baseReview.getContras();
    }

    public UgcAutoReviewWrapper addContras(final String... contras) {
        return wrapBaseReview(baseReview.addContras(contras));
    }

    @SuppressWarnings("unchecked")
    public UgcAutoReviewWrapper addContras(final Collection<String> contras) {
        return wrapBaseReview(baseReview.addContras(contras));
    }

    public UgcAutoReviewWrapper setContras(final String... contras) {
        return wrapBaseReview(baseReview.setContras(contras));
    }

    public UgcAutoReviewWrapper setContras(final Collection<String> contras) {
        return wrapBaseReview(baseReview.setContras(contras));
    }

    @Override
    public String getId() {
        return baseReview.getId();
    }

    public UgcAutoReviewWrapper setId(final String id) {
        return wrapBaseReview(baseReview.setId(id));
    }

    @Override
    public Float getRating() {
        return baseReview.getRating();
    }

    public UgcAutoReviewWrapper setRating(final Float rating) {
        return wrapBaseReview(baseReview.setRating(rating));
    }

    @Override
    public Float getBestRating() {
        return baseReview.getBestRating();
    }

    public UgcAutoReviewWrapper setBestRating(final float bestRating) {
        return wrapBaseReview(baseReview.setBestRating(bestRating));
    }

    @Override
    public Float getWorstRating() {
        return baseReview.getWorstRating();
    }

    public UgcAutoReviewWrapper setWorstRating(final float worstRating) {
        return wrapBaseReview(baseReview.setWorstRating(worstRating));
    }

    @Override
    public Author getReviewer() {
        return baseReview.getReviewer();
    }

    public UgcAutoReviewWrapper setReviewer(final Author reviewer) {
        return wrapBaseReview(baseReview.setReviewer(reviewer));
    }

    @Override
    public Date getReviewedDate() {
        return baseReview.getReviewedDate();
    }

    public UgcAutoReviewWrapper setReviewedDate(final Date reviewedDate) {
        return wrapBaseReview(baseReview.setReviewedDate(reviewedDate));
    }

    @Override
    public String getPermanentId() {
        return baseReview.getPermanentId();
    }

    public UgcAutoReviewWrapper setPermanentId(final String permanentId) {
        return wrapBaseReview(baseReview.setPermanentId(permanentId));
    }

    @Override
    public String getVersionId() {
        return baseReview.getVersionId();
    }

    public UgcAutoReviewWrapper setVersionId(final String versionId) {
        return wrapBaseReview(baseReview.setVersionId(versionId));
    }

    @Override
    public String getDescription() {
        return baseReview.getDescription();
    }

    public UgcAutoReviewWrapper setDescription(final String description) {
        return wrapBaseReview(baseReview.setDescription(description));
    }

    @Override
    public List<AutoModeration> getModerationHistory() {
        return baseReview.getModerationHistory();
    }

    public UgcAutoReviewWrapper setModerationHistory(final List<AutoModeration> history) {
        return wrapBaseReview(baseReview.setModerationHistory(history));
    }

    public UgcAutoReviewWrapper setModerationHistory(final AutoModeration... history) {
        return wrapBaseReview(baseReview.setModerationHistory(history));
    }

    public UgcAutoReviewWrapper addModerationHistory(final List<AutoModeration> history) {
        return wrapBaseReview(baseReview.addModerationHistory(history));
    }

    public UgcAutoReviewWrapper addModerationHistory(final AutoModeration... history) {
        return wrapBaseReview(baseReview.addModerationHistory(history));
    }

    @Override
    public Long getUid() {
        return review.getUid();
    }

    public UgcAutoReviewWrapper setUid(final Long uid) {
        return new UgcAutoReviewWrapper(this) {
            @Override
            public Long getUid() {
                return uid;
            }
        };
    }

    @Override
    public boolean isDeleted() {
        return baseReview.isDeleted();
    }

    public UgcAutoReviewWrapper setDeleted(final boolean isDeleted) {
        return wrapBaseReview(baseReview.setDeleted(isDeleted));
    }

    @Override
    public String getOwningTime() {
        return review.getOwningTime();
    }

    public UgcAutoReviewWrapper setOwningTime(final String owningTime) {
        return new UgcAutoReviewWrapper(this) {
            @Override
            public String getOwningTime() {
                return owningTime;
            }
        };
    }

    @Override
    public Long getCreatedTime() {
        return review.getCreatedTime();
    }

    public UgcAutoReviewWrapper setCreatedTime(final Long createdTime) {
        return new UgcAutoReviewWrapper(this) {
            @Override
            public Long getCreatedTime() {
                return createdTime;
            }
        };
    }

    @Override
    public Long getLastModificationTime() {
        return review.getLastModificationTime();
    }

    public UgcAutoReviewWrapper setLastModificationTime(final Long lastModificationTime) {
        return new UgcAutoReviewWrapper(this) {
            @Override
            public Long getLastModificationTime() {
                return lastModificationTime;
            }
        };
    }

    @Override
    public List<String> getPhotoUrls() {
        return baseReview.getPhotoUrls();
    }

    public UgcAutoReviewWrapper setPhotoUrls(final List<String> photoUrls) {
        return wrapBaseReview(baseReview.setPhotoUrls(photoUrls));
    }

    public UgcAutoReviewWrapper setPhotoUrls(final String... photoUrls) {
        return setPhotoUrls(Arrays.asList(photoUrls));
    }

    @SuppressWarnings("unchecked")
    public UgcAutoReviewWrapper addPhotoUrls(final List<String> photoUrls) {
        return wrapBaseReview(baseReview.addPhotoUrls(photoUrls));
    }


    @Override
    public UserIdentity getUserIdentity() {
        return review.getUserIdentity();
    }

    public UgcAutoReviewWrapper setUserIdentity(final UserIdentity userIdentity) {
        return new UgcAutoReviewWrapper(this) {
            @Override
            public UserIdentity getUserIdentity() {
                return userIdentity;
            }
        };
    }

    @Override
    public String getPreviousId() {
        return review.getPreviousId();
    }

    public UgcAutoReviewWrapper setPreviousId(final String previousId) {
        return new UgcAutoReviewWrapper(this) {
            @Override
            public String getPreviousId() {
                return previousId;
            }
        };
    }

    @Override
    public String getDomain() {
        return review.getDomain();
    }

    public UgcAutoReviewWrapper setDomain(final String locale) {
        return new UgcAutoReviewWrapper(this) {
            @Override
            public String getDomain() {
                return locale;
            }
        };
    }

    @Override
    public Locale getUiLanguage() {
        return review.getUiLanguage();
    }

    public UgcAutoReviewWrapper setUiLanguage(final Locale language) {
        return new UgcAutoReviewWrapper(this) {
            @Override
            public Locale getUiLanguage() {
                return language;
            }
        };
    }

    @Override
    public Integer getUsefulCount() {
        return baseReview.getUsefulCount();
    }

    public UgcAutoReviewWrapper setUsefulCount(final Integer usefulCount) {
        return wrapBaseReview(baseReview.setUsefulCount(usefulCount));
    }

    @Override
    public Integer getUselessCount() {
        return review.getUselessCount();
    }

    public UgcAutoReviewWrapper setUselessCount(final Integer uselessCount) {
        return wrapBaseReview(baseReview.setUselessCount(uselessCount));
    }


    private UgcAutoReviewWrapper wrapBaseReview(final BaseAutoReviewWrapper baseReview) {
        return new UgcAutoReviewWrapper(this, baseReview);
    }

    private final static UgcAutoReviewWrapper EMPTY_UGC_AUTO_REVIEW_WRAPPER = new UgcAutoReviewWrapper(new UgcAutoReview() {
        @Override
        public String getSummary() {
            return null;
        }

        @Override
        public Date getWatchTime() {
            return null;
        }

        @Override
        public HProduct getItem() {
            return null;
        }

        @Override
        public Collection<String> getPhotos() {
            return Collections.emptyList();
        }

        @Override
        public Collection<String> getPros() {
            return Collections.emptyList();
        }

        @Override
        public Collection<String> getContras() {
            return Collections.emptyList();
        }

        @Override
        public String getId() {
            return null;
        }

        @Override
        public Float getRating() {
            return null;
        }

        @Override
        public Float getBestRating() {
            return null;
        }

        @Override
        public Float getWorstRating() {
            return null;
        }

        @Override
        public Author getReviewer() {
            return null;
        }

        @Override
        public Date getReviewedDate() {
            return null;
        }

        @Override
        public String getPermanentId() {
            return null;
        }

        @Override
        public String getVersionId() {
            return null;
        }

        @Override
        public String getDescription() {
            return null;
        }

        @Override
        public List<AutoModeration> getModerationHistory() {
            return Collections.emptyList();
        }

        @Override
        public Long getUid() {
            return null;
        }

        @Override
        public boolean isDeleted() {
            return false;
        }

        @Override
        public String getOwningTime() {
            return null;
        }

        @Override
        public Long getCreatedTime() {
            return null;
        }

        @Override
        public Long getLastModificationTime() {
            return null;
        }

        @Override
        public UserIdentity getUserIdentity() {
            return null;
        }

        @Override
        public String getPreviousId() {
            return null;
        }

        @Override
        public Integer getUsefulCount() {
            return null;
        }

        @Override
        public Integer getUselessCount() {
            return null;
        }

        @Override
        public List<String> getPhotoUrls() {
            return Collections.emptyList();
        }

        @Override
        public String getLanguage() {
            return null;
        }

        @Override
        public String getDomain() {
            return null;
        }

        @Override
        public Locale getUiLanguage() {
            return null;
        }
    });
}

