package ru.yandex.webmaster3.core.semantic.semantic_document_parser.microformats.spec.instances;

import org.jetbrains.annotations.NotNull;
import org.w3c.dom.Node;
import ru.yandex.webmaster3.core.semantic.semantic_document_parser.microformats.data.MicroformatData;
import ru.yandex.webmaster3.core.semantic.semantic_document_parser.microformats.exceptions.*;
import ru.yandex.webmaster3.core.semantic.semantic_document_parser.microformats.spec.*;
import ru.yandex.webmaster3.core.semantic.semantic_document_parser.microformats.spec.property_types.DatetimeProperty;
import ru.yandex.webmaster3.core.semantic.semantic_document_parser.microformats.spec.property_types.IDProperty;
import ru.yandex.webmaster3.core.semantic.semantic_document_parser.microformats.spec.property_types.TextProperty;
import ru.yandex.webmaster3.core.semantic.semantic_document_parser.microformats.spec.property_types.URIProperty;

public class HCalendarEvent extends Microformat {
    final private static HCalendarEvent instance = new HCalendarEvent("vevent", true);

    /**
     * the name should be equal to the header of microformat (e. g. "vcard")
     *
     * @param name
     */
    protected HCalendarEvent(@NotNull final String name, final boolean root) {
        super(name, root);
    }

    static {
        try {
            instance.addProperty(
                    new MFPropertySingular("dtstamp", DatetimeProperty.getInstance(), TextProperty.getInstance()));
            instance.addProperty(
                    new MFPropertySingular("dtstart", DatetimeProperty.getInstance(), TextProperty.getInstance()));
            instance.addProperty(
                    new MFPropertySingular("dtend", DatetimeProperty.getInstance(), TextProperty.getInstance()));
            instance.addProperty(
                    new MFPropertySingular("duration", DatetimeProperty.getInstance(), TextProperty.getInstance()));
            instance.addProperty(new MFPropertySingular("summary", TextProperty.getInstance()));
            instance.addProperty(
                    new MFPropertySingularSpec("location", HCard.getInstance(), Adr.getInstance(), Geo.getInstance(),
                            TextProperty.getInstance()));
            instance.addProperty(new MFPropertySingular("geo", Geo.getInstance(), TextProperty.getInstance()));
            instance.addProperty(new MFPropertySingular("uid", URIProperty.getInstance(), IDProperty.getInstance(),
                    TextProperty.getInstance()));
            instance.addProperty(new MFPropertySingular("url", URIProperty.getInstance(), TextProperty.getInstance()));
            instance.addProperty(new MFPropertyPlural("rdate", TextProperty.getInstance()));
            instance.addProperty(new MFPropertyPlural("rrule", TextProperty.getInstance()));
            instance.addProperty(new MFPropertySingular("class", TextProperty.getInstance()));
            instance.addProperty(new MFPropertyPlural("category", TextProperty.getInstance()));
            instance.addProperty(new MFPropertySingular("description", TextProperty.getInstance()));
            instance.addProperty(new MFPropertyPlural("attendee", Attendee.getInstance(), HCard.getInstance(),
                    URIProperty.getInstance(), TextProperty.getInstance()));
            instance.addProperty(new MFPropertyPlural("contact", HCard.getInstance(), URIProperty.getInstance(),
                    TextProperty.getInstance()));
            instance.addProperty(new MFPropertySingular("organizer", HCard.getInstance(), URIProperty.getInstance(),
                    TextProperty.getInstance()));
            instance.addProperty(new MFPropertyPlural("attach", URIProperty.getInstance(), TextProperty.getInstance()));
            instance.addProperty(new MFPropertySingular("status", TextProperty.getInstance()));
            instance.addProperty(new MFPropertyRel("tag"));
        } catch (InvalidActionException e) {
            e.printStackTrace();
        }
        instance.freeze();
    }

    public static HCalendarEvent getInstance() {
        return instance;
    }

    @Override
    public boolean postProcess(@NotNull final MicroformatData data, @NotNull final String content, final Node node) throws EmptyMFException, MFExceptions, InvalidActionException {
        if (data.isEmpty()) {
            throw new EmptyMFException(getName());
        }
        final MFExceptions ex = new MFExceptions(getName());
        if (data.isEmpty("dtstart")) {
            //check required
            ex.put(new PropertyNotDefinedMFException("dtstart",data.getLocation()));
        }
        if (data.isEmpty("summary")) {
            //check required
            ex.put(new PropertyNotDefinedMFException("summary",data.getLocation()));
        }
        if (!data.isEmpty("dtend") && !data.isEmpty("duration")) {
            //at most one of either
            ex.put(new ExplictFieldsMFException("dtend | duration", true, data.getLocation()));
        }
        if (!ex.isEmpty()) {
            throw ex;
        }
        return false;
    }
}
