/*
 * Copyright (C) 2015 Google Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
 * in compliance with the License. You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software distributed under the License
 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
 * or implied. See the License for the specific language governing permissions and limitations under
 * the License.
 */
package com.google.cloud.genomics.utils.grpc;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;

import java.io.IOException;
import java.security.GeneralSecurityException;
import java.util.Iterator;
import java.util.List;

import org.junit.BeforeClass;
import org.junit.Ignore;
import org.junit.Test;

import com.google.cloud.genomics.utils.IntegrationTestHelper;
import com.google.cloud.genomics.utils.ShardBoundary;
import com.google.cloud.genomics.utils.ShardUtils;
import com.google.common.collect.ImmutableList;
import com.google.genomics.v1.StreamVariantsRequest;
import com.google.genomics.v1.StreamVariantsResponse;
import com.google.genomics.v1.Variant;

public class VariantStreamIteratorITCase {

  static IntegrationTestHelper helper;

  @BeforeClass
  public static void setUpBeforeClass() throws Exception {
    helper = new IntegrationTestHelper();
  }

  @Test
  public void testBasic() throws IOException, GeneralSecurityException {
    ImmutableList<StreamVariantsRequest> requests =
        ShardUtils.getVariantRequests(helper.PLATINUM_GENOMES_VARIANTSET,
            helper.PLATINUM_GENOMES_KLOTHO_REFERENCES, 100L);
    assertEquals(1, requests.size());

    Iterator<StreamVariantsResponse> iter =
        VariantStreamIterator.enforceShardBoundary(requests.get(0), helper.getAuth(),
            ShardBoundary.Requirement.OVERLAPS, null);

    assertTrue(iter.hasNext());
    StreamVariantsResponse variantResponse = iter.next();
    List<Variant> variants = variantResponse.getVariantsList();
    // This includes the klotho SNP and three non-variant segments which overlap it.
    assertEquals(4, variants.size());
    assertFalse(iter.hasNext());
    
    iter =
        VariantStreamIterator.enforceShardBoundary(requests.get(0), helper.getAuth(),
            ShardBoundary.Requirement.STRICT, null);

    assertTrue(iter.hasNext());
    variantResponse = iter.next();
    // This includes only the klotho SNP.
    assertEquals(1, variantResponse.getVariantsList().size());
    assertFalse(iter.hasNext());
  }

  @Test
  @Ignore
  // TODO https://github.com/googlegenomics/utils-java/issues/48
  public void testPartialResponses() throws IOException, GeneralSecurityException {
    ImmutableList<StreamVariantsRequest> requests =
        ShardUtils.getVariantRequests(helper.PLATINUM_GENOMES_VARIANTSET,
            helper.PLATINUM_GENOMES_KLOTHO_REFERENCES, 100L);
    assertEquals(1, requests.size());

    Iterator<StreamVariantsResponse> iter =
        VariantStreamIterator.enforceShardBoundary(requests.get(0), helper.getAuth(),
            ShardBoundary.Requirement.STRICT, "variants(reference_name,start)");

    assertTrue(iter.hasNext());
    StreamVariantsResponse variantResponse = iter.next();
    List<Variant> variants = variantResponse.getVariantsList();
    // This includes only the klotho SNP.
    assertEquals(1, variants.size());
    assertFalse(iter.hasNext());
    
    assertEquals("chr13", variants.get(0).getReferenceName());
    assertEquals(33628137, variants.get(0).getStart());
    assertNull(variants.get(0).getReferenceBases());
  }

  // TODO test a shard where the entire first result will be empty due to the strict shard boundary requirement.  Same for reads.
  
  /**
   * TODO: Retry tests.  Same for reads.
   * 
   * Be sure to test retries that occur at:
   * (1) the beginning of the stream
   * (2) within records that overlap the start position
   * (3) occur at the start position
   * (4) beyond the start position
   *
   * Test should confirm that all records are returned only once upon successful completion of the retried stream.
   */
  
}

@@ -2739,32 +2739,871 @@
 asNext());%0A  %7D%0A%0A
+  @Test%0A  public void testEmptyRegion() throws IOException, GeneralSecurityException %7B%0A    ImmutableList%3CStreamVariantsRequest%3E requests =%0A        ShardUtils.getVariantRequests(helper.PLATINUM_GENOMES_VARIANTSET,%0A            %22chrDoesNotExist:100:200%22, 100L);%0A    assertEquals(1, requests.size());%0A%0A    Iterator%3CStreamVariantsResponse%3E iter =%0A        VariantStreamIterator.enforceShardBoundary(requests.get(0), helper.getAuth(),%0A            ShardBoundary.Requirement.OVERLAPS, null);%0A    assertFalse(iter.hasNext());%0A%0A    iter =%0A        VariantStreamIterator.enforceShardBoundary(requests.get(0), helper.getAuth(),%0A            ShardBoundary.Requirement.STRICT, null);%0A    assertFalse(iter.hasNext());%0A  %7D%0A%0A  // TODO test a shard where the entire first result will be empty due to the strict shard boundary requirement.  Same for reads.%0A   %0A
   @Test%0A  @Ignor
@@ -4645,141 +4645,8 @@
  %7D%0A%0A
-  // TODO test a shard where the entire first result will be empty due to the strict shard boundary requirement.  Same for reads.%0A  %0A
   /*

Add empty region integration test.