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

import org.htmlcleaner.TagNode;
import org.jetbrains.annotations.NotNull;
import org.w3c.dom.Node;
import ru.yandex.webmaster3.core.semantic.semantic_document_parser.microformats.data.MFAnyData;
import ru.yandex.webmaster3.core.semantic.semantic_document_parser.microformats.data.MFPropertyData;
import ru.yandex.webmaster3.core.semantic.semantic_document_parser.microformats.data.MFPropertySingularData;
import ru.yandex.webmaster3.core.semantic.semantic_document_parser.microformats.data.MicroformatData;
import ru.yandex.webmaster3.core.semantic.semantic_document_parser.microformats.exceptions.*;

public class MFPropertySingular extends MFProperty {

    public MFPropertySingular(@NotNull final String name, @NotNull final MFType... possibleTypes) {
        super(name, possibleTypes);
    }

    @Override
    public MFPropertySingularData createData() {
        return new MFPropertySingularData(this);
    }

    @Override
    public String toShortString(@NotNull final MFPropertyData mfPropertyData) throws InvalidActionException {
        final MFPropertySingularData data = (MFPropertySingularData) mfPropertyData;
        if (data.isEmpty()) {
            return "";
        }
        return toShortString(data.getData());
    }

    @Override
    public String toDebugString(@NotNull final MFPropertyData mfPropertyData, @NotNull final String indent) throws InvalidActionException {
        final MFPropertySingularData data = (MFPropertySingularData) mfPropertyData;
        if (data.isEmpty()) {
            return "";
        }
        return toDebugString(data.getData(), indent);
    }

    /**
     * Override it to change politics related to multiple definitions for singular properties
     *
     * @param data
     * @param newData
     * @throws InvalidDataMFException
     */
    synchronized public void addData(@NotNull final MFPropertySingularData data, @NotNull final MFAnyData newData) throws InvalidDataMFException {
        if (newData.isEmpty()) {
            throw new EmptyMFException(getName(), data.getLocation());
        }
        if (data.getData() != null) {
            throw new MultipleDefinitionsForSingularMFException(getName(),data.getLocation());
        }
        //data.setData(newData);
        data.giveMethodsTo(this);
        methods.setData(newData);
        methods = null;
    }

    /**
     * Override it to change post processing for existing singular properties
     * It does not need to be overriden if you overrided post processing for microformat
     *
     *
     * @param data
     * @param content
     * @param node
     * @param microformatData
     * @throws MFException
     */
    public boolean postProcess(final MFPropertySingularData data, @NotNull final String content, final Node node, final MicroformatData microformatData) throws MFException {
        return false;
    }

    @Override
    public final void addData(@NotNull final MFPropertyData data, @NotNull final MFAnyData newData) throws InvalidDataMFException {
        addData((MFPropertySingularData) data, newData);
    }

    @Override
    public  final boolean postProcess(final MFPropertyData mfPropertyData, @NotNull final String content, final Node node, final MicroformatData microformatData) throws MFException {
        return postProcess((MFPropertySingularData) mfPropertyData, content, node, microformatData);
    }

    @Override
    public boolean postProcess(MFPropertyData mfPropertyData, @NotNull String content, TagNode node, MicroformatData microformatData) throws MFException {
        return false;
    }


    protected MFPropertySingularData.Methods methods; //temporal data

    synchronized public void receiveMethods(final MFPropertySingularData.Methods methods) {
        this.methods = methods;
    }
}
