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


import com.google.common.collect.Collections2;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import ru.yandex.webmaster3.core.openapi.internal.JSON;
import ru.yandex.webmaster3.core.semantic.review_business.biz.model.BizReview;
import ru.yandex.webmaster3.core.semantic.review_business.model.impl.json.AuthorJsonConversions;
import ru.yandex.webmaster3.core.semantic.review_business.model.impl.json.LinkToOriginReviewJsonConversions;
import ru.yandex.webmaster3.core.semantic.review_business.util.DateHelper;

import static org.apache.commons.collections.CollectionUtils.isEmpty;
import static ru.yandex.webmaster3.core.semantic.review_business.biz.model.impl.BizReviewAttributes.*;
import static ru.yandex.webmaster3.core.semantic.review_business.biz.model.impl.HCardAttributes.GEO;

/**
 * TODO
 *
 * @author Dima Schitinin <dimas@yandex-team.ru>
 */
public final class BizReviewJsonConversions {
    private static final Logger log = LoggerFactory.getLogger(BizReviewJsonConversions.class);

    private BizReviewJsonConversions() {
    }

    /**
     * Use {@link #fromJson(String)} (throws {@link }) instead
     */
    @Deprecated
    public static BizReview fromJson(final JSONObject json) {
        return new BizReviewOverJson(json);
    }

    public static BizReview fromJson(final String json) throws JSONException {
        return new BizReviewOverJson(json);
    }

    public static JSONObject toJson(final BizReview bizReview)
            throws JSONException {
        return new JSONObject().
                putOpt(ID, bizReview.getId()).
                putOpt(BIZ_ID, bizReview.getBizId()).
                putOpt(AUTO_BIZ_ID, bizReview.getAutoBizId()).
                putOpt(
                        EXCLUDED_BIZ_IDS,
                        isEmpty(bizReview.getExcludedBizIds()) ? null : new JSONArray(bizReview.getExcludedBizIds())
                ).
                putOpt(CHAIN_ID, bizReview.getChainId()).
                putOpt(CATEGORY, bizReview.getCategory()).
                putOpt(BIZ_RUBRICS, isEmpty(bizReview.getBizRubrics()) ? null : new JSONArray(bizReview.getBizRubrics())).
                putOpt(LANGUAGE, bizReview.getLanguage()).
                putOpt(RATING, bizReview.getRating()).
                putOpt(BEST_RATING, bizReview.getBestRating()).
                putOpt(WORST_RATING, bizReview.getWorstRating()).
                putOpt(SUMMARY, bizReview.getSummary()).
                putOpt(DESCRIPTION, bizReview.getDescription()).
                putOpt(REVIEWER, bizReview.getReviewer() == null ?
                        null : AuthorJsonConversions.toJson(bizReview.getReviewer())).
                putOpt(ITEM, bizReview.getItem() == null ?
                        null : HCardJsonConversions.toJson(bizReview.getItem())).
                putOpt(REVIEWED_DATE,
                        bizReview.getReviewedDate() == null ?
                                null : DateHelper.write(bizReview.getReviewedDate())).
                putOpt(VISITED_DATE, bizReview.getVisitedDate()).
                putOpt(PROS, isEmpty(bizReview.getPros()) ? null : new JSONArray(bizReview.getPros())).
                putOpt(CONTRAS, isEmpty(bizReview.getContras()) ? null : new JSONArray(bizReview.getContras())).
                putOpt(USEFUL, bizReview.getUsefulCount()).
                putOpt(USELESS, bizReview.getUselessCount()).
                putOpt(LIKES, bizReview.getLikesCount()).
                putOpt(COMMENTS, bizReview.getCommentsCount()).
                putOpt(REVIEWS_URL, bizReview.getReviewsUrl()).
                putOpt(COMMENT_URL, bizReview.getCommentsUrl()).
                putOpt(TAGS, isEmpty(bizReview.getTags()) ?
                        null : new JSONArray(Collections2.transform(bizReview.getTags(), TagJsonConversions.TAG_TO_JSON))).
                putOpt(FACTS, isEmpty(bizReview.getFacts()) ?
                        null : new JSONArray(Collections2.transform(bizReview.getFacts(), TagJsonConversions.TAG_TO_JSON))).
                putOpt(URL, bizReview.getUrl()).
                putOpt(ORIGIN_REVIEW,
                        bizReview.getOriginReview() != null ?
                                LinkToOriginReviewJsonConversions.toJson(bizReview.getOriginReview()) :
                                null
                ).
                putOpt(PERMANENT_ID, bizReview.getPermanentId()).
                putOpt(VERSION_ID, bizReview.getVersionId()).
                putOpt(SOURCE_ID, bizReview.getSourceId()).
                putOpt(IS_DELETED, bizReview.isDeleted() ? Boolean.TRUE : null).
                putOpt(MODERATION_HISTORY, bizReview.hasModeration() ?
                        new JSONArray(Collections2.transform(bizReview.getModerationHistory(),
                                Moderation2JsonConversions.MODERATION_TO_JSON)) :
                        null).
                putOpt(WATCH_TIME,
                        bizReview.getWatchTime() == null ?
                                null : DateHelper.write(bizReview.getWatchTime())).
                putOpt(SPECIALIST_ID, bizReview.getSpecialistId()).
                putOpt(IS_VERIFIED, bizReview.isVerified() ? Boolean.TRUE : null).
                putOpt(GEO, bizReview.getGeo() != null ? GeoJsonConversions.toJson(bizReview.getGeo()) : null);
    }

    /**
     * Use {@link #safeToJsonString(ru.yandex.webmaster3.core.semantic.review_business.biz.model.BizReview)} instead
     */
    @Deprecated
    public static JSONObject safeToJson(final BizReview bizReview) {
        try {
            return toJson(bizReview);
        } catch (JSONException e) {
            log.error(
                    "Error while convert BizReview to JSON", e);
            return null;
        }
    }

    public static String toJsonString(final BizReview bizReview) throws JSONException {
        JSONObject obj;
        obj = toJson(bizReview);
        return obj.toString();
    }

    public static String safeToJsonString(final BizReview bizReview) {
        try {
            return toJsonString(bizReview);
        } catch (JSONException e) {
            log.error("Error while convert BizReview to JSON", e);
            return null;
        }
    }


}

