/*
 * The Exomiser - A tool to annotate and prioritize genomic variants
 *
 * Copyright (c) 2016-2018 Queen Mary University of London.
 * Copyright (c) 2012-2016 Charité Universitätsmedizin Berlin and Genome Research Ltd.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package org.monarchinitiative.exomiser.core.phenotype.service;

import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Sets;
import org.monarchinitiative.exomiser.core.phenotype.PhenotypeMatch;
import org.monarchinitiative.exomiser.core.phenotype.PhenotypeTerm;

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

/**
 * Test helper to provide real, canned data for a small set of
 * @author Jules Jacobsen <jules.jacobsen@sanger.ac.uk>
 */
public class TestOntologyService implements OntologyService {


    private final Map<String, PhenotypeTerm> hpIdPhenotypeTerms;

    private final Map<PhenotypeTerm, List<PhenotypeMatch>> humanHumanMappings;
    private final Map<PhenotypeTerm, List<PhenotypeMatch>> humanMouseMappings;
    private final Map<PhenotypeTerm, List<PhenotypeMatch>> humanFishMappings;

    private TestOntologyService(Builder builder) {
        this.hpIdPhenotypeTerms = builder.hpIdPhenotypeTerms;
        this.humanHumanMappings = builder.humanHumanMappings;
        this.humanMouseMappings = builder.humanMouseMappings;
        this.humanFishMappings = builder.humanFishMappings;
    }

    @Override
    public Set<PhenotypeTerm> getHpoTerms() {
        return ImmutableSet.copyOf(hpIdPhenotypeTerms.values());
    }

    @Override
    public Set<PhenotypeTerm> getMpoTerms() {
        return Collections.emptySet();
    }

    @Override
    public Set<PhenotypeTerm> getZpoTerms() {
        return Collections.emptySet();
    }

    @Override
    public Set<PhenotypeMatch> getHpoMatchesForHpoTerm(PhenotypeTerm hpoTerm) {
        List<PhenotypeMatch> matches = humanHumanMappings.get(hpoTerm);
        return (matches == null) ? Collections.emptySet() : Sets.newHashSet(matches);
    }

    @Override
    public Set<PhenotypeMatch> getMpoMatchesForHpoTerm(PhenotypeTerm hpoTerm) {
        List<PhenotypeMatch> matches = humanMouseMappings.get(hpoTerm);
        return (matches == null) ? Collections.emptySet() : Sets.newHashSet(matches);
    }

    @Override
    public Set<PhenotypeMatch> getZpoMatchesForHpoTerm(PhenotypeTerm hpoTerm) {
        List<PhenotypeMatch> matches = humanFishMappings.get(hpoTerm);
        return (matches == null) ? Collections.emptySet() : Sets.newHashSet(matches);
    }

    @Override
    public PhenotypeTerm getPhenotypeTermForHpoId(String hpoId) {
        return hpIdPhenotypeTerms.getOrDefault(hpoId, PhenotypeTerm.of(hpoId, "Not set"));
    }

    @Override
    public List<String> getCurrentHpoIds(List<String> hpoIds) {
        return hpoIds;
    }

    public static Builder builder() {
        return new Builder();
    }

    public static class Builder {

        private Map<String, PhenotypeTerm> hpIdPhenotypeTerms = Collections.emptyMap();

        private Map<PhenotypeTerm, List<PhenotypeMatch>> humanHumanMappings = Collections.emptyMap();
        private Map<PhenotypeTerm, List<PhenotypeMatch>> humanMouseMappings = Collections.emptyMap();
        private Map<PhenotypeTerm, List<PhenotypeMatch>> humanFishMappings = Collections.emptyMap();


        private Builder() {
        }

        public Builder setHpIdPhenotypeTerms(Map<String, PhenotypeTerm> hpIdPhenotypeTerms) {
            this.hpIdPhenotypeTerms = hpIdPhenotypeTerms;
            return this;
        }

        public Builder setHumanHumanMappings(Map<PhenotypeTerm, List<PhenotypeMatch>> humanHumanMappings) {
            this.humanHumanMappings = humanHumanMappings;
            return this;
        }

        public Builder setHumanMouseMappings(Map<PhenotypeTerm, List<PhenotypeMatch>> humanMouseMappings) {
            this.humanMouseMappings = humanMouseMappings;
            return this;
        }

        public Builder setHumanFishMappings(Map<PhenotypeTerm, List<PhenotypeMatch>> humanFishMappings) {
            this.humanFishMappings = humanFishMappings;
            return this;
        }

        public TestOntologyService build() {
            return new TestOntologyService(this);
        }
    }
}

@@ -96,10 +96,10 @@
 6-20
-18
+20
  Que
@@ -954,16 +954,64 @@
 rvice;%0A%0A
+import com.google.common.collect.ImmutableList;%0A
 import c
@@ -1579,16 +1579,78 @@
 peTerms;
+%0A    private final Map%3CString, String%3E obsoleteToCurrentTerms;
 %0A%0A    pr
@@ -2173,24 +2173,94 @@
 shMappings;%0A
+        this.obsoleteToCurrentTerms = builder.obsoleteToCurrentTerms;%0A
     %7D%0A%0A    @
@@ -3651,16 +3651,192 @@
 n hpoIds
+.stream()%0A                .map(hpoId -%3E obsoleteToCurrentTerms.getOrDefault(hpoId, hpoId))%0A                .distinct()%0A                .collect(ImmutableList.toImmutableList())
 ;%0A    %7D%0A
@@ -4033,16 +4033,101 @@
 tyMap();
+%0A        private Map%3CString, String%3E obsoleteToCurrentTerms = Collections.emptyMap();
 %0A%0A      
@@ -5156,32 +5156,32 @@
 FishMappings) %7B%0A
-
             this
@@ -5248,32 +5248,229 @@
 his;%0A        %7D%0A%0A
+        public Builder setObsoleteToCurrentTerms(Map%3CString, String%3E obsoleteToCurrentTerms) %7B%0A            this.obsoleteToCurrentTerms = obsoleteToCurrentTerms;%0A            return this;%0A        %7D%0A%0A
         public T

Add new obsoleteToCurrentTerms method to TestOntologyService.Builder