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

import ru.yandex.webmaster3.core.semantic.review_business.biz.model.*;
import ru.yandex.webmaster3.core.semantic.review_business.model.Author;
import ru.yandex.webmaster3.core.semantic.review_business.model.LinkToOriginReview;
import ru.yandex.webmaster3.core.semantic.review_business.model.UserIdentity;

import java.util.*;

/**
 * Immutable implementation of {@link UgcBizReview}
 * that on each modification call returns new instance.
 * <p/>
 * User: willzyx
 * Date: 3/30/12 - 7:02 PM
 */
public class UgcBizReviewWrapper extends UgcBizReview {

    public static UgcBizReviewWrapper newUgcBizReview() {
        return EMPTY_UGC_BIZ_REVIEW_WRAPPER;
    }

    private final BizReviewWrapper bizReview;
    private final UgcBizReview ugcBizReview;

    public UgcBizReviewWrapper(final UgcBizReview ugcBizReview) {
        this(new BizReviewWrapper(ugcBizReview), ugcBizReview);
    }

    private UgcBizReviewWrapper(final BizReviewWrapper bizReview, final UgcBizReview ugcBizReview) {
        this.ugcBizReview = ugcBizReview;
        this.bizReview = bizReview;
    }

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

    public UgcBizReviewWrapper setId(final String id) {
        return wrapBizReview(bizReview.setId(id));
    }

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

    public UgcBizReviewWrapper setLanguage(String language) {
        return wrapBizReview(bizReview.setLanguage(language));
    }

    @Override
    public String getType() {
        return bizReview.getType();
    }

    @Override
    public Long getBizId() {
        return bizReview.getBizId();
    }

    public UgcBizReviewWrapper setBizId(final Long bizId) {
        return wrapBizReview(bizReview.setBizId(bizId));
    }

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

    @Override
    public Collection<Long> getExcludedBizIds() {
        return Collections.emptySet();
    }

    @Override
    public Long getChainId() {
        return bizReview.getChainId();
    }

    public UgcBizReviewWrapper setChainId(Long chainId) {
        return wrapBizReview(bizReview.setChainId(chainId));
    }

    @Override
    public BizCategory getCategory() {
        return bizReview.getCategory();
    }

    @Override
    public Collection<String> getBizRubrics() {
        return bizReview.getBizRubrics();
    }

    public UgcBizReviewWrapper setBizRubrics(final Collection<String> rubrics) {
        return wrapBizReview(bizReview.setBizRubrics(rubrics));
    }

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

    public UgcBizReviewWrapper setRating(final Float rating) {
        return wrapBizReview(bizReview.setRating(rating));
    }

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

    public UgcBizReviewWrapper setBestRating(final Float bestRating) {
        return wrapBizReview(bizReview.setBestRating(bestRating));
    }

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

    public UgcBizReviewWrapper setWorstRating(final Float worstRating) {
        return wrapBizReview(bizReview.setWorstRating(worstRating));
    }

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

    public UgcBizReviewWrapper setReviewer(final Author reviewer) {
        return wrapBizReview(bizReview.setReviewer(reviewer));
    }

    @Override
    public HCard getItem() {
        return bizReview.getItem();
    }

    public UgcBizReviewWrapper setItem(final HCard item) {
        return wrapBizReview(bizReview.setItem(item));
    }

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

    public UgcBizReviewWrapper setSummary(final String summary) {
        return wrapBizReview(bizReview.setSummary(summary));
    }

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

    public UgcBizReviewWrapper setDescription(final String description) {
        return wrapBizReview(bizReview.setDescription(description));
    }

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

    public UgcBizReviewWrapper addPros(final String... pros) {
        return wrapBizReview(bizReview.addPros(pros));
    }

    public UgcBizReviewWrapper addPros(final Collection<String> pros) {
        return wrapBizReview(bizReview.addPros(pros));
    }

    public UgcBizReviewWrapper setPros(final Collection<String> pros) {
        return wrapBizReview(bizReview.setPros(pros));
    }

    public UgcBizReviewWrapper setPros(final String... pros) {
        return wrapBizReview(bizReview.setPros(pros));
    }

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

    public UgcBizReviewWrapper addContras(final String... contras) {
        return wrapBizReview(bizReview.addContras(contras));
    }

    public UgcBizReviewWrapper addContras(final Collection<String> contras) {
        return wrapBizReview(bizReview.addContras(contras));
    }

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

    public UgcBizReviewWrapper setUsefulCount(final Integer usefulCount) {
        return wrapBizReview(bizReview.setUsefulCount(usefulCount));
    }

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

    public UgcBizReviewWrapper setUselessCount(final Integer uselessCount) {
        return wrapBizReview(bizReview.setUselessCount(uselessCount));
    }

    @Override
    public Integer getLikesCount() {
        return bizReview.getLikesCount();
    }

    public UgcBizReviewWrapper setLikesCount(final Integer likesCount) {
        return wrapBizReview(bizReview.setLikesCount(likesCount));
    }

    @Override
    public Integer getCommentsCount() {
        return bizReview.getCommentsCount();
    }

    public UgcBizReviewWrapper setCommentsCount(final Integer commentsCount) {
        return wrapBizReview(bizReview.setCommentsCount(commentsCount));
    }

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

    public UgcBizReviewWrapper setReviewedDate(final Date reviewedDate) {
        return wrapBizReview(bizReview.setReviewedDate(reviewedDate));
    }

    @Override
    public String getVisitedDate() {
        return bizReview.getVisitedDate();
    }

    public UgcBizReviewWrapper setVisitedDate(final String visitedDate) {
        return wrapBizReview(bizReview.setVisitedDate(visitedDate));
    }

    @Override
    public String getReviewsUrl() {
        return bizReview.getReviewsUrl();
    }

    public UgcBizReviewWrapper setReviewsUrl(final String reviewsUrl) {
        return wrapBizReview(bizReview.setReviewsUrl(reviewsUrl));
    }

    @Override
    public String getCommentsUrl() {
        return bizReview.getCommentsUrl();
    }

    public UgcBizReviewWrapper setCommentsUrl(final String commentsUrl) {
        return wrapBizReview(bizReview.setCommentsUrl(commentsUrl));
    }

    @Override
    public Collection<Tag> getTags() {
        return bizReview.getTags();
    }

    public UgcBizReviewWrapper addTags(final Tag... tags) {
        return wrapBizReview(bizReview.addTags(tags));
    }

    public UgcBizReviewWrapper addTags(final Collection<Tag> tags) {
        return wrapBizReview(bizReview.addTags(tags));
    }

    public UgcBizReviewWrapper setTags(final Collection<Tag> tags) {
        return wrapBizReview(bizReview.setTags(tags));
    }

    @Override
    public Collection<Tag> getFacts() {
        return bizReview.getFacts();
    }

    public UgcBizReviewWrapper addFacts(final Tag... tags) {
        return wrapBizReview(bizReview.addFacts(tags));
    }

    public UgcBizReviewWrapper addFacts(final Collection<Tag> tags) {
        return wrapBizReview(bizReview.addFacts(tags));
    }

    public UgcBizReviewWrapper setFacts(final Collection<Tag> tags) {
        return wrapBizReview(bizReview.setFacts(tags));
    }


    @Override
    public String getUrl() {
        return bizReview.getUrl();
    }

    public UgcBizReviewWrapper setUrl(final String url) {
        return wrapBizReview(bizReview.setUrl(url));
    }

    @Override
    public LinkToOriginReview getOriginReview() {
        return bizReview.getOriginReview();
    }

    public UgcBizReviewWrapper setOriginReview(LinkToOriginReview link) {
        return wrapBizReview(bizReview.setOriginReview(link));
    }

    @Override
    public Long getSourceId() {
        return bizReview.getSourceId();
    }

    public UgcBizReviewWrapper setSourceId(final Long sourceId) {
        return wrapBizReview(bizReview.setSourceId(sourceId));
    }

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

    public UgcBizReviewWrapper setPermanentId(final String permanentId) {
        return wrapBizReview(bizReview.setPermanentId(permanentId));
    }

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

    public UgcBizReviewWrapper setVersionId(final String versionId) {
        return wrapBizReview(bizReview.setVersionId(versionId));
    }

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

    public UgcBizReviewWrapper setDeleted(boolean isDeleted) {
        return wrapBizReview(bizReview.setDeleted(isDeleted));
    }

    @Override
    public List<Moderation2> getModerationHistory() {
        return bizReview.getModerationHistory();
    }

    public UgcBizReviewWrapper setModerationHistory(final List<Moderation2> history) {
        return wrapBizReview(bizReview.setModerationHistory(history));
    }

    public UgcBizReviewWrapper setModerationHistory(final Moderation2... history) {
        return wrapBizReview(bizReview.setModerationHistory(history));
    }

    public UgcBizReviewWrapper addModerationHistory(final List<Moderation2> history) {
        return wrapBizReview(bizReview.addModerationHistory(history));
    }

    public UgcBizReviewWrapper addModerationHistory(final Moderation2... history) {
        return wrapBizReview(bizReview.addModerationHistory(history));
    }

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

    @Override
    public String getSpecialistId() {
        return bizReview.getSpecialistId();
    }

    @Override
    public boolean isVerified() {
        return bizReview.isVerified();
    }

    @Override
    public Geo getGeo() {
        return bizReview.getGeo();
    }

    public UgcBizReviewWrapper setGeo(final Geo geo) {
        return new UgcBizReviewWrapper(this) {
            @Override
            public Geo getGeo() {
                return geo;
            }
        };
    }

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

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

    @Override
    public String getUuid() {
        return ugcBizReview.getUuid();
    }

    public UgcBizReviewWrapper setUuid(final String uuid) {
        return new UgcBizReviewWrapper(this) {
            @Override
            public String getUuid() {
                return uuid;
            }
        };
    }

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

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

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

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

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

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

    @Override
    @Deprecated
    public String getCommentFromBusiness() {
        return null;
    }

    @Override
    public Comment getComment() {
        return ugcBizReview.getComment();
    }

    public UgcBizReviewWrapper setComment(final Comment comment) {
        return new UgcBizReviewWrapper(this) {
            @Override
            public Comment getComment() {
                return comment;
            }
        };
    }

    @Override
    public String getPreviousVersionId() {
        return ugcBizReview.getPreviousVersionId();
    }

    public UgcBizReviewWrapper setPreviousVersionId(final String previousVersionId) {
        return new UgcBizReviewWrapper(this) {
            @Override
            public String getPreviousVersionId() {
                return previousVersionId;
            }
        };
    }

    @Override
    public SourceType getSourceType() {
        return ugcBizReview.getSourceType();
    }

    public UgcBizReviewWrapper setSourceType(final SourceType st) {
        return new UgcBizReviewWrapper(this) {
            @Override
            public SourceType getSourceType() {
                return st;
            }
        };
    }

    private UgcBizReviewWrapper wrapBizReview(final BizReviewWrapper bizReview) {
        return new UgcBizReviewWrapper(bizReview, this);
    }


    private static final UgcBizReviewWrapper EMPTY_UGC_BIZ_REVIEW_WRAPPER =
            new UgcBizReviewWrapper(new UgcBizReview() {
                @Override
                public String getLanguage() {
                    return null;
                }

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

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

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

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

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

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

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

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

                @Override
                public Set<Long> getExcludedBizIds() {
                    return Collections.emptySet();
                }

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

                @Override
                public BizCategory getCategory() {
                    return null;
                }

                @Override
                public Collection<String> getBizRubrics() {
                    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 HCard getItem() {
                    return null;
                }

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

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

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

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

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

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

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

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

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

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

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

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

                @Override
                public Collection<Tag> getTags() {
                    return Collections.emptyList();
                }

                @Override
                public Collection<Tag> getFacts() {
                    return Collections.emptyList();
                }

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

                @Override
                public LinkToOriginReview getOriginReview() {
                    return null;
                }

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

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

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

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

                @Override
                public Comment getComment() {
                    return null;
                }

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

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

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

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

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

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

                @Override
                public Geo getGeo() {
                    return null;
                }

                @Override
                public SourceType getSourceType() {
                    return null;
                }
            });
}

