package in.cdac.medinfo.csnotk.csnolib.ecl.constraint;

import org.snomed.langauges.ecl.domain.refinement.EclRefinement;
import org.snomed.langauges.ecl.domain.refinement.SubRefinement;
//Changes
import in.cdac.medinfo.csnotk.csnolib.model.Concept;
import java.util.Set;
import java.util.List;
import com.google.common.collect.Sets;
import static com.google.common.collect.Sets.newHashSet;
import static java.util.stream.Collectors.toSet;

public class SEclRefinement extends EclRefinement implements SConstraint {

    @Override
    public Set<Concept> addQuery() {
        Set<Concept> finalSctIds = null;
        if (getDisjunctionSubRefinements() != null) {
            finalSctIds = ((SConstraint) getSubRefinement()).addQuery();
            for (SubRefinement disjunctionSubRefinement : getDisjunctionSubRefinements()) {
                finalSctIds = Sets.union( finalSctIds,((SConstraint) disjunctionSubRefinement).addQuery());
            }
        } else {
            finalSctIds = ((SConstraint) getSubRefinement()).addQuery();
            for (SubRefinement conjunctionSubRefinement : getConjunctionSubRefinements()) {
                finalSctIds = Sets.intersection( finalSctIds,((SConstraint) conjunctionSubRefinement).addQuery());
            }
        }
        return finalSctIds;
    }

    @Override
    public SSubRefinement getSubRefinement() {
        return (SSubRefinement) super.getSubRefinement();
    }

    @Override
    public Set<String> getConceptIds() {
        Set<String> conceptIds = newHashSet(((SSubRefinement) subRefinement).getConceptIds());
        if ((conjunctionSubRefinements != null) && !conjunctionSubRefinements.isEmpty()) {
            conceptIds.addAll(getConceptIds(conjunctionSubRefinements));
        }
        if ((disjunctionSubRefinements != null) && !disjunctionSubRefinements.isEmpty()) {
            conceptIds.addAll(getConceptIds(disjunctionSubRefinements));
        }
        return conceptIds;
    }

    private Set<String> getConceptIds(List<SubRefinement> subRefinements) {
        return subRefinements.stream()
                .map(SSubRefinement.class::cast)
                .map(SSubRefinement::getConceptIds)
                .flatMap(Set::stream)
                .collect(toSet());
    }

}
