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

import ru.yandex.common.util.collections.Cf;
import ru.yandex.common.util.collections.Either;
import ru.yandex.common.util.collections.Pair;
import ru.yandex.common.util.xml.Xmler;

import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;

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: 8/8/11
 * Time: 5:46 PM
 * To change this template use File | Settings | File Templates.
 */
public class Organization extends XmlStructData {

    private final String name;
    private final List<String> urls;
    private final List<Phone> phones;
    private final List<String> emails;
    private final Geo geo;
    private final List<Address> addresses;
    private final String workhours;
    private final List<String> categories;
    private final String cat;

    //not implemented to output
    private final List<Either<Xmler.Tag, String>> agents;
    private final String class_;
    private final List<String> keys;
    private final List<String> labels;
    private final List<String> logos;
    private final List<String> mailers;
    private final List<String> notes;
    private final List<String> photos;
    private final String rev;
    private final List<String> titles;
    private final List<String> tags;

    private final List<Pair<String, String>> optionalParts;
    private final String sourceUrl;

    public Xmler.Tag toXml() {
        final List<Xmler.Tag> tags = new LinkedList<Xmler.Tag>();
        if (sourceUrl != null) {
            tags.add(tag("source-url", sourceUrl));
        }
        if (phones != null) {
            for (final Phone phone : phones) {
                tags.add(phone.toXml());
            }
        }
        if (emails != null) {
            for (final String email : emails) {
                tags.add(tag("email", email));
            }
        }
        if (urls != null) {
            for (final String url : urls) {
                tags.add(tag("url", url));
            }
        }
        if (addresses != null) {
            for (final Address adr : addresses) {
                tags.add(adr.toXml());
            }
        }
        if (geo != null) {
            tags.add(geo.toXml());
        }
        if (workhours != null) {
            tags.add(tag("workhours", workhours));
        }
        if (categories != null) {
            for (final String category : categories) {
                tags.add(tag("category", category));
            }
        }
        if (optionalParts != null) {
            for (final Pair<String, String> opt : optionalParts) {
                if (opt.second != null) {
                    tags.add(tag(opt.first, opt.second));
                }
            }
        }
        if (cat != null) {
            tags.add(tag("cat-id", cat));
        }
        return tag("vcard", attribute("fn", name), tags);
    }

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

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

    public Organization(final String name, final List<String> urls, final List<Phone> phones, final List<String> emails, final Geo geo, final List<Address> addresses, final String workhours, final List<String> categories, final String cat, final List<Either<Xmler.Tag, String>> agents, final String class_, final List<String> keys, final List<String> labels, final List<String> logos, final List<String> mailers, final List<String> notes, final List<String> photos, final String rev, final List<String> titles, final List<String> tags, final List<Pair<String, String>> optionalParts, final String sourceUrl) {
        this.name = name;
        this.urls = urls;
        this.phones = phones;
        this.emails = emails;
        this.geo = geo;
        this.addresses = addresses;
        this.workhours = workhours;
        this.categories = categories;
        this.cat = cat;
        this.agents = agents;
        this.class_ = class_;
        this.keys = keys;
        this.labels = labels;
        this.logos = logos == null ? Collections.<String>emptyList() : logos;
        this.mailers = mailers;
        this.notes = notes;
        this.photos = photos == null ? Collections.<String>emptyList() : photos;
        this.rev = rev;
        this.titles = titles;
        this.tags = tags;
        this.optionalParts = optionalParts;
        this.sourceUrl = sourceUrl;
    }

    public String getName() {
        return name;
    }

    public List<String> getUrls() {
        return urls;
    }

    public List<Phone> getPhones() {
        return phones;
    }

    public List<String> getEmails() {
        return emails;
    }

    public Geo getGeo() {
        return geo;
    }

    public List<Address> getAddresses() {
        return addresses;
    }

    public String getWorkhours() {
        return workhours;
    }

    public List<String> getCategories() {
        return categories;
    }

    public String getCat() {
        return cat;
    }

    public List<Either<Xmler.Tag, String>> getAgents() {
        return agents;
    }

    public String getClass_() {
        return class_;
    }

    public List<String> getKeys() {
        return keys;
    }

    public List<String> getLabels() {
        return labels;
    }

    public List<String> getLogos() {
        return logos;
    }

    public List<String> getMailers() {
        return mailers;
    }

    public List<String> getNotes() {
        return notes;
    }

    public List<String> getPhotos() {
        return photos;
    }

    public String getRev() {
        return rev;
    }

    public List<String> getTitles() {
        return titles;
    }

    public List<String> getTags() {
        return tags;
    }

    public List<Pair<String, String>> getOptionalParts() {
        return optionalParts;
    }

    public String getSourceUrl() {
        return sourceUrl;
    }

    @Override
    public boolean equals(final Object o) {
        if (this == o) {
            return true;
        }
        if (!(o instanceof Organization)) {
            return false;
        }

        final Organization that = (Organization) o;

        if (addresses != null ? !addresses.equals(that.addresses) : that.addresses != null) {
            return false;
        }
        if (agents != null ? !agents.equals(that.agents) : that.agents != null) {
            return false;
        }
        if (cat != null ? !cat.equals(that.cat) : that.cat != null) {
            return false;
        }
        if (categories != null ? !categories.equals(that.categories) : that.categories != null) {
            return false;
        }
        if (class_ != null ? !class_.equals(that.class_) : that.class_ != null) {
            return false;
        }
        if (emails != null ? !emails.equals(that.emails) : that.emails != null) {
            return false;
        }
        if (geo != null ? !geo.equals(that.geo) : that.geo != null) {
            return false;
        }
        if (keys != null ? !keys.equals(that.keys) : that.keys != null) {
            return false;
        }
        if (labels != null ? !labels.equals(that.labels) : that.labels != null) {
            return false;
        }
        if (logos != null ? !logos.equals(that.logos) : that.logos != null) {
            return false;
        }
        if (mailers != null ? !mailers.equals(that.mailers) : that.mailers != null) {
            return false;
        }
        if (name != null ? !name.equals(that.name) : that.name != null) {
            return false;
        }
        if (notes != null ? !notes.equals(that.notes) : that.notes != null) {
            return false;
        }
        if (phones != null ? !phones.equals(that.phones) : that.phones != null) {
            return false;
        }
        if (photos != null ? !photos.equals(that.photos) : that.photos != null) {
            return false;
        }
        if (rev != null ? !rev.equals(that.rev) : that.rev != null) {
            return false;
        }
        if (tags != null ? !tags.equals(that.tags) : that.tags != null) {
            return false;
        }
        if (titles != null ? !titles.equals(that.titles) : that.titles != null) {
            return false;
        }
        if (urls != null ? !urls.equals(that.urls) : that.urls != null) {
            return false;
        }
        return !(workhours != null ? !workhours.equals(that.workhours) : that.workhours != null);

    }

    @Override
    public int hashCode() {
        int result = name != null ? name.hashCode() : 0;
        result = 31 * result + (urls != null ? urls.hashCode() : 0);
        result = 31 * result + (phones != null ? phones.hashCode() : 0);
        result = 31 * result + (emails != null ? emails.hashCode() : 0);
        result = 31 * result + (geo != null ? geo.hashCode() : 0);
        result = 31 * result + (addresses != null ? addresses.hashCode() : 0);
        result = 31 * result + (workhours != null ? workhours.hashCode() : 0);
        result = 31 * result + (categories != null ? categories.hashCode() : 0);
        result = 31 * result + (cat != null ? cat.hashCode() : 0);
        result = 31 * result + (agents != null ? agents.hashCode() : 0);
        result = 31 * result + (class_ != null ? class_.hashCode() : 0);
        result = 31 * result + (keys != null ? keys.hashCode() : 0);
        result = 31 * result + (labels != null ? labels.hashCode() : 0);
        result = 31 * result + (logos != null ? logos.hashCode() : 0);
        result = 31 * result + (mailers != null ? mailers.hashCode() : 0);
        result = 31 * result + (notes != null ? notes.hashCode() : 0);
        result = 31 * result + (photos != null ? photos.hashCode() : 0);
        result = 31 * result + (rev != null ? rev.hashCode() : 0);
        result = 31 * result + (titles != null ? titles.hashCode() : 0);
        result = 31 * result + (tags != null ? tags.hashCode() : 0);
        return result;
    }
}
