package org.gbif.occurrence.processor.identifiers;

import org.gbif.api.model.crawler.DwcaValidationReport;
import org.gbif.api.model.crawler.OccurrenceValidationReport;
import org.gbif.api.vocabulary.OccurrenceSchemaType;

import javax.annotation.Nullable;

import com.google.common.base.Objects;

import static com.google.common.base.Preconditions.checkNotNull;

/**
 * A simple class to determine whether triplets and/or occurrenceIds are valid as identifiers for the given dataset.
 */
public class IdentifierStrategy {

  private final boolean tripletsValid;
  private final boolean occurrenceIdsValid;

  public IdentifierStrategy(OccurrenceSchemaType schemaType, @Nullable DwcaValidationReport validationReport) {
    checkNotNull(schemaType, "schemaType can't be null");
    if (schemaType == OccurrenceSchemaType.DWCA) {
      checkNotNull(validationReport, "validationReport can't be null if schema is DWCA");
      checkNotNull(validationReport.getOccurrenceReport(), "validation.occurrenceReport can't be null if schema is DWCA");
    }
    tripletsValid = tripletsValid(schemaType, validationReport);
    occurrenceIdsValid = occurrenceIdsValid(schemaType, validationReport);
  }

  /**
   * For XML datasets triplets are always valid. For DwC-A datasets triplets are valid if there are more than 0 unique
   * triplets in the dataset, and exactly 0 triplets referenced by more than one record.
   */
  private static boolean tripletsValid(OccurrenceSchemaType schemaType, DwcaValidationReport validationReport) {
    boolean valid = true;
    if (schemaType == OccurrenceSchemaType.DWCA) {
      OccurrenceValidationReport report = validationReport.getOccurrenceReport();
      valid = report.getUniqueTriplets() > 0
              && report.getCheckedRecords() - report.getRecordsWithInvalidTriplets() == report.getUniqueTriplets();
    }

    return valid;
  }

  /**
   * For XML datasets occurrenceIds are ignored. For DwC-A datasets occurrenceIds are valid if each record has a unique
   * occurrenceId.
   */
  private static boolean occurrenceIdsValid(OccurrenceSchemaType schemaType, DwcaValidationReport validationReport) {
    boolean valid = false;
    if (schemaType == OccurrenceSchemaType.DWCA) {
      OccurrenceValidationReport report = validationReport.getOccurrenceReport();
      valid = report.getCheckedRecords() > 0 && report.getUniqueOccurrenceIds() == report.getCheckedRecords();
    }

    return valid;
  }

  public boolean isTripletsValid() {
    return tripletsValid;
  }

  public boolean isOccurrenceIdsValid() {
    return occurrenceIdsValid;
  }

  @Override
  public int hashCode() {
    return Objects.hashCode(tripletsValid, occurrenceIdsValid);
  }

  @Override
  public boolean equals(Object obj) {
    if (this == obj) {
      return true;
    }
    if (obj == null || getClass() != obj.getClass()) {
      return false;
    }
    final IdentifierStrategy other = (IdentifierStrategy) obj;
    return Objects.equal(this.tripletsValid, other.tripletsValid) && Objects
      .equal(this.occurrenceIdsValid, other.occurrenceIdsValid);
  }
}

@@ -971,16 +971,24 @@
 eport(),
+%0A       
  %22valida
@@ -1692,32 +1692,40 @@
 );%0A      valid =
+%0A       
  report.getUniqu
@@ -1743,22 +1743,8 @@
  %3E 0
-%0A             
  && 
@@ -1816,24 +1816,35 @@
 () == report
+%0A          
 .getUniqueTr
@@ -1933,13 +1933,21 @@
 are 
-ignor
+always accept
 ed. 
@@ -2009,28 +2009,28 @@
 rd has a
+%0A   *
  unique
-%0A   *
  occurre
@@ -2180,20 +2180,19 @@
 valid = 
-fals
+tru
 e;%0A    i

change to always accept occurrenceId from xml sources (fixes BGBM bug)