package ru.yandex.webmaster3.core.semantic.semantic_document_parser.struct_data;

import ru.yandex.common.util.collections.Cf;
import ru.yandex.common.util.json.JsonConvertable;
import ru.yandex.common.util.json.JsonConvertableWithKey;
import ru.yandex.common.util.json.Jsonable;
import ru.yandex.common.util.json.Jsoner;
import ru.yandex.common.util.xml.Xmler;

import java.util.*;

import static ru.yandex.common.util.json.Jsoner.pair;
import static ru.yandex.common.util.xml.Xmler.attribute;
import static ru.yandex.common.util.xml.Xmler.tag;

/**
 * Created by IntelliJ IDEA.
 * User: rasifiel
 * Date: 3/5/12
 * Time: 11:39 AM
 */
public class EncArticle extends XmlStructData implements JsonConvertable, Jsonable {

    private final String titile;
    private final String content;
    private final List<String> categories;
    private final String references;
    private final String author;
    private final String source;
    private final String sourceDate;
    private final List<String> photos;
    public final String sourceUrl;
    public final String sourceType;


    public EncArticle(final String titile, final String content, final List<String> categories, final String references, final String author, final String source, final String sourceDate, final List<String> photos, final String sourceUrl, final String sourceType) {
        this.titile = titile;
        this.content = content;
        this.sourceUrl = sourceUrl;
        this.sourceType = sourceType;
        this.categories = categories == null ? Collections.<String>emptyList() : categories;
        this.references = references;
        this.author = author;
        this.source = source;
        this.sourceDate = sourceDate;
        this.photos = photos == null ? Collections.<String>emptyList() : photos;
    }

    public Xmler.Tag toXml() {
        final List<Xmler.Tag> tags = new LinkedList<Xmler.Tag>();
        if (sourceUrl != null) {
            tags.add(tag("src", attribute("url", sourceUrl)));
        }
        if (titile != null) {
            tags.add(tag("title", titile));
        }
        if (content != null) {
            tags.add(tag("content", content));
        }
        if (references != null) {
            tags.add(tag("references", references));
        }
        if (author != null) {
            tags.add(tag("author", author));
        }
        if (source != null) {
            tags.add(tag("source", source));
        }
        if (sourceDate != null) {
            tags.add(tag("source-date", sourceDate));
        }
        for (final String category : categories) {
            tags.add(tag("category", category));
        }
        for (final String photo : photos) {
            tags.add(tag("photo", photo));
        }
        return tag("enc-article", attribute("source", sourceType), tags);
    }

    private Set<String> TAGS = Collections.unmodifiableSet(Cf.set("enc-article"));

    @Override
    public Set<String> getEntityTags() {
        return TAGS;
    }

    @Override
    public boolean equals(final Object o) {
        if (this == o) {
            return true;
        }
        if (o == null || getClass() != o.getClass()) {
            return false;
        }

        final EncArticle that = (EncArticle) o;

        if (author != null ? !author.equals(that.author) : that.author != null) {
            return false;
        }
        if (categories != null ? !categories.equals(that.categories) : that.categories != null) {
            return false;
        }
        if (content != null ? !content.equals(that.content) : that.content != null) {
            return false;
        }
        if (photos != null ? !photos.equals(that.photos) : that.photos != null) {
            return false;
        }
        if (references != null ? !references.equals(that.references) : that.references != null) {
            return false;
        }
        if (source != null ? !source.equals(that.source) : that.source != null) {
            return false;
        }
        if (sourceDate != null ? !sourceDate.equals(that.sourceDate) : that.sourceDate != null) {
            return false;
        }
        if (sourceType != null ? !sourceType.equals(that.sourceType) : that.sourceType != null) {
            return false;
        }
        if (sourceUrl != null ? !sourceUrl.equals(that.sourceUrl) : that.sourceUrl != null) {
            return false;
        }
        return !(titile != null ? !titile.equals(that.titile) : that.titile != null);

    }

    @Override
    public int hashCode() {
        int result = titile != null ? titile.hashCode() : 0;
        result = 31 * result + (content != null ? content.hashCode() : 0);
        result = 31 * result + (categories != null ? categories.hashCode() : 0);
        result = 31 * result + (references != null ? references.hashCode() : 0);
        result = 31 * result + (author != null ? author.hashCode() : 0);
        result = 31 * result + (source != null ? source.hashCode() : 0);
        result = 31 * result + (sourceDate != null ? sourceDate.hashCode() : 0);
        result = 31 * result + (photos != null ? photos.hashCode() : 0);
        result = 31 * result + (sourceUrl != null ? sourceUrl.hashCode() : 0);
        result = 31 * result + (sourceType != null ? sourceType.hashCode() : 0);
        return result;
    }

    @Override
    public Jsoner.JsonObject asJson() {
        final List<JsonConvertableWithKey> result = new LinkedList<JsonConvertableWithKey>();
        if (sourceType != null) {
            result.add(pair("type", sourceType));
        }
        if (titile != null) {
            result.add(pair("title", titile));
        }
        if (content != null) {
            result.add(pair("content", Jsoner.arrayOfSimples(content)));
        }
        if (references != null) {
            result.add(pair("references", references));
        }
        if (author != null) {
            result.add(pair("author", author));
        }
        if (source != null) {
            result.add(pair("source", source));
        }
        if (sourceDate != null) {
            result.add(pair("sourceDate", sourceDate));
        }
        if (!categories.isEmpty()) {
            final Jsoner.JsonArray categoriesArray = Jsoner.arrayOfSimples(categories);
            result.add(pair("category", categoriesArray));
        }
        if (!photos.isEmpty()) {
            final Jsoner.JsonArray categoriesArray = Jsoner.arrayOfSimples(photos);
            result.add(pair("photo", categoriesArray));
        }
        return Jsoner.object(result);
    }

    @Override
    public void toJson(final StringBuilder storage) {
        asJson().toJson(storage);
    }
}
