/*
 * Copyright (c) 2012 The Broad Institute
 *
 * Permission is hereby granted, free of charge, to any person
 * obtaining a copy of this software and associated documentation
 * files (the "Software"), to deal in the Software without
 * restriction, including without limitation the rights to use,
 * copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following
 * conditions:
 *
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
 * THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */

package htsjdk.variant.variantcontext;

// the imports for unit testing.

import htsjdk.variant.VariantBaseTest;
import htsjdk.variant.vcf.VCFConstants;
import java.util.Arrays;
import org.testng.Assert;
import org.testng.annotations.BeforeSuite;
import org.testng.annotations.Test;

public class GenotypeUnitTest extends VariantBaseTest {
    Allele A, Aref, T;

    @BeforeSuite
    public void before() {
        A = Allele.create("A");
        Aref = Allele.create("A", true);
        T = Allele.create("T");
    }

    private static final GenotypeBuilder makeGB() {
        return new GenotypeBuilder("misc");
    }

    @Test
    public void testFilters() {
        Assert.assertFalse(makeGB().make().isFiltered(), "by default Genotypes must be PASS");
        Assert.assertNull(makeGB().make().getFilters(), "by default Genotypes must be PASS => getFilters() == null");
        Assert.assertFalse(
                makeGB().filter(null).make().isFiltered(), "setting filter == null => Genotypes must be PASS");
        Assert.assertNull(makeGB().filter(null).make().getFilters(), "Genotypes PASS => getFilters == null");
        Assert.assertFalse(
                makeGB().filter("PASS").make().isFiltered(), "setting filter == PASS => Genotypes must be PASS");
        Assert.assertNull(makeGB().filter("PASS").make().getFilters(), "Genotypes PASS => getFilters == null");
        Assert.assertTrue(makeGB().filter("x").make().isFiltered(), "setting filter != null => Genotypes must be PASS");
        Assert.assertEquals(
                makeGB().filter("x").make().getFilters(), "x", "Should get back the expected filter string");
        Assert.assertEquals(
                makeGB().filters("x", "y").make().getFilters(),
                "x;y",
                "Multiple filter field values should be joined with ;");
        Assert.assertEquals(
                makeGB().filters("x", "y", "z").make().getFilters(),
                "x;y;z",
                "Multiple filter field values should be joined with ;");
        Assert.assertTrue(
                makeGB().filters("x", "y", "z").make().isFiltered(), "Multiple filter values should be filtered");
        Assert.assertEquals(
                makeGB().filter("x;y;z").make().getFilters(),
                "x;y;z",
                "Multiple filter field values should be joined with ;");
        Assert.assertEquals(
                makeGB().filter("x;y;z").make().getAnyAttribute(VCFConstants.GENOTYPE_FILTER_KEY),
                "x;y;z",
                "getAnyAttribute(GENOTYPE_FILTER_KEY) should return the filter");
        Assert.assertTrue(
                makeGB().filter("x;y;z").make().hasAnyAttribute(VCFConstants.GENOTYPE_FILTER_KEY),
                "hasAnyAttribute(GENOTYPE_FILTER_KEY) should return true");
        Assert.assertTrue(
                makeGB().make().hasAnyAttribute(VCFConstants.GENOTYPE_FILTER_KEY),
                "hasAnyAttribute(GENOTYPE_FILTER_KEY) should return true");
        Assert.assertFalse(makeGB().filter("").make().isFiltered(), "empty filters should count as unfiltered");
        Assert.assertEquals(
                makeGB().filter("").make().getFilters(), null, "empty filter string should result in null filters");
    }

    @Test
    public void testHasAltAllele() {
        Assert.assertTrue(GenotypeBuilder.create("s", Arrays.asList(A)).hasAltAllele());
        Assert.assertTrue(GenotypeBuilder.create("s", Arrays.asList(A, Aref)).hasAltAllele());
        Assert.assertTrue(
                GenotypeBuilder.create("s", Arrays.asList(A, Allele.NO_CALL)).hasAltAllele());
        Assert.assertFalse(GenotypeBuilder.create("s", Arrays.asList(Aref)).hasAltAllele());
        Assert.assertFalse(
                GenotypeBuilder.create("s", Arrays.asList(Aref, Aref)).hasAltAllele());
        Assert.assertFalse(GenotypeBuilder.create("s", Arrays.asList(Allele.NO_CALL, Allele.NO_CALL))
                .hasAltAllele());
        Assert.assertTrue(GenotypeBuilder.create("s", Arrays.asList(Allele.NON_REF_ALLELE))
                .hasAltAllele());
        Assert.assertTrue(
                GenotypeBuilder.create("s", Arrays.asList(Allele.SPAN_DEL)).hasAltAllele());
    }

    @Test
    public void testHasRefAllele() {
        Assert.assertFalse(GenotypeBuilder.create("s", Arrays.asList(A)).hasRefAllele());
        Assert.assertTrue(GenotypeBuilder.create("s", Arrays.asList(A, Aref)).hasRefAllele());
        Assert.assertFalse(
                GenotypeBuilder.create("s", Arrays.asList(A, Allele.NO_CALL)).hasRefAllele());
        Assert.assertTrue(GenotypeBuilder.create("s", Arrays.asList(Aref)).hasRefAllele());
        Assert.assertTrue(GenotypeBuilder.create("s", Arrays.asList(Aref, Aref)).hasRefAllele());
        Assert.assertFalse(GenotypeBuilder.create("s", Arrays.asList(Allele.NO_CALL, Allele.NO_CALL))
                .hasRefAllele());
    }

    //    public Genotype(String sampleName, List<Allele> alleles, double negLog10PError, Set<String> filters,
    // Map<String, ?> attributes, boolean isPhased) {
    //    public Genotype(String sampleName, List<Allele> alleles, double negLog10PError, Set<String> filters,
    // Map<String, ?> attributes, boolean isPhased, double[] log10Likelihoods) {
    //    public Genotype(String sampleName, List<Allele> alleles, double negLog10PError, double[] log10Likelihoods)
    //    public Genotype(String sampleName, List<Allele> alleles, double negLog10PError)
    //    public Genotype(String sampleName, List<Allele> alleles)
    //    public List<Allele> getAlleles()
    //    public List<Allele> getAlleles(Allele allele)
    //    public Allele getAllele(int i)
    //    public boolean isPhased()
    //    public int getPloidy()
    //    public Type getType()
    //    public boolean isHom()
    //    public boolean isHomRef()
    //    public boolean isHomVar()
    //    public boolean isHet()
    //    public boolean isNoCall()
    //    public boolean isCalled()
    //    public boolean isAvailable()
    //    public boolean hasLikelihoods()
    //    public GenotypeLikelihoods getLikelihoods()
    //    public boolean sameGenotype(Genotype other)
    //    public boolean sameGenotype(Genotype other, boolean ignorePhase)
    //    public String getSampleName()
    //    public boolean hasLog10PError()
    //    public double getLog10PError()
    //    public double getPhredScaledQual()
    //    public boolean hasExtendedAttribute(String key)
    //    public Object getExtendedAttribute(String key)
    //    public Object getExtendedAttribute(String key, Object defaultValue)
    //    public String getAttributeAsString(String key, String defaultValue)
    //    public int getAttributeAsInt(String key, int defaultValue)
    //    public double getAttributeAsDouble(String key, double  defaultValue)
    //    public boolean getAttributeAsBoolean(String key, boolean  defaultValue)
}
