package org.pharmgkb.pharmcat.util;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Set;
import javax.annotation.Nonnull;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import org.pharmgkb.pharmcat.reporter.model.VariantReport;
import org.pharmgkb.pharmcat.reporter.model.result.GeneReport;


/**
 * This class will handle calling UGT1A1 diplotypes based on single variant position genotypes. This should only be used
 * in the case of a GeneCall that is either unphased or phased with multiple calls.
 *
 * @author Ryan Whaley
 */
public class Ugt1a1AlleleMatcher {

  private static final List<String> sf_groupA = ImmutableList.of("*28", "*80");
  private static final List<String> sf_groupB = ImmutableList.of("*6", "*27", "*37");
  private static final List<String> sf_groupAB = new ArrayList<>();
  static {
    sf_groupAB.addAll(sf_groupA);
    sf_groupAB.addAll(sf_groupB);
  }

  /**
   * Makes diplotype calls (i.e. *1/*80) based on variant report information in the given {@link GeneReport}
   * @param report a Gene Reprot
   * @return a Set of diplotype calls (i.e. "*1/*80")
   */
  public static Set<String> makeLookupCalls(GeneReport report) {
    Preconditions.checkNotNull(report);
    Preconditions.checkArgument(report.getGene().equals("UGT1A1"), "Can only be used on UGT1A1");

    boolean geneMissing = report.getVariantReports().stream().allMatch(VariantReport::isMissing);
    if (geneMissing) {
      return ImmutableSet.of();
    }

    List<String> haplotypes = matchHaplotypes(report);

    long countHomoAB = sf_groupAB.stream()
        .filter(a -> haplotypes.stream().filter(h -> h.equals(a)).count() >= 2)
        .count();
    long countHetA = sf_groupA.stream()
        .filter(a -> haplotypes.stream().filter(h -> h.equals(a)).count() >= 1)
        .count();
    long countHetB = sf_groupB.stream()
        .filter(a -> haplotypes.stream().filter(h -> h.equals(a)).count() >= 1)
        .count();

    if (countHomoAB >= 2 || (countHetA >= 1 && countHetB >= 1) || countHetB >= 2) {
      return ImmutableSet.of("*80/*80");
    }
    else if (countHetA == 0 && countHetB == 0) {
      return ImmutableSet.of("*1/*1");
    }
    else {
      return ImmutableSet.of("*1/*80");
    }
  }

  /**
   * Generates a list of found Haplotype names in this {@link GeneReport} based on {@link VariantReport} data.
   * @param report a {@link GeneReport} for the UGT1A1 gene
   */
  private static List<String> matchHaplotypes(@Nonnull GeneReport report) {

    List<String> haplotypes = new ArrayList<>();

    for (VariantReport variant : report.getVariantReports()) {
      String[] alleles = variant.getCall().split("[|/]");

      if (variant.getPosition() == 233757013) {
        Arrays.stream(alleles)
            .filter(a -> a.equals("G"))
            .forEach(a -> haplotypes.add("*60"));
      }

      if (variant.getPosition() == 233759924) {
        Arrays.stream(alleles)
            .filter(a -> a.equals("T"))
            .forEach(a -> haplotypes.add("*80"));
      }

      if (variant.getPosition() == 233760498) {
        Arrays.stream(alleles)
            .filter(a -> a.equals("A"))
            .forEach(a -> haplotypes.add("*6"));
      }

      if (variant.getPosition() == 233760973) {
        Arrays.stream(alleles)
            .filter(a -> a.equals("A"))
            .forEach(a -> haplotypes.add("*27"));
      }

      if (variant.getPosition() == 233760233) {
        Arrays.stream(alleles)
            .filter(a -> a.equals("CATAT"))
            .forEach(a -> haplotypes.add("*28"));
        Arrays.stream(alleles)
            .filter(a -> a.equals("C"))
            .forEach(a -> haplotypes.add("*36"));
        Arrays.stream(alleles)
            .filter(a -> a.equals("CATATAT"))
            .forEach(a -> haplotypes.add("*37"));
      }
    }
    return haplotypes;
  }
}

@@ -2720,24 +2720,90 @@
 eports()) %7B%0A
+      if (variant.getCall() == null) %7B%0A        continue;%0A      %7D%0A%0A
       String

Fix UGT1A1 allele matcher