// Path: src/java/com/google/cloud/bigquery/dwhassessment/extractiontool/common/ChunkCheckpoint.java
// @AutoValue
// public abstract class ChunkCheckpoint {
// 
//   public abstract Integer lastSavedChunkNumber();
// 
//   public abstract Instant lastSavedInstant();
// 
//   public static Builder builder() {
//     return new AutoValue_ChunkCheckpoint.Builder()
//         .setLastSavedChunkNumber(-1)
//         .setLastSavedInstant(Instant.ofEpochMilli(0));
//   }
// 
//   @AutoValue.Builder
//   public abstract static class Builder {
// 
//     public abstract Builder setLastSavedChunkNumber(Integer value);
// 
//     public abstract Builder setLastSavedInstant(Instant value);
// 
//     public abstract ChunkCheckpoint build();
//   }
// }


import static java.util.stream.Collectors.toList;
import static java.util.stream.Collectors.groupingBy;
import static java.util.stream.Collectors.mapping;
import static java.util.stream.Collectors.collectingAndThen;
import com.google.cloud.bigquery.dwhassessment.extractiontool.common.ChunkCheckpoint;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Iterables;
import com.google.re2j.Matcher;
import com.google.re2j.Pattern;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder;
import java.time.format.DateTimeParseException;
import java.util.Comparator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.function.Function;
          .filter(Files::isRegularFile)
          .map(oneFile -> INPUT_CHUNK_PATTERN.matcher(oneFile.getFileName().toString()))
          .filter(Matcher::matches)
          .collect(
              groupingBy(
                  (Matcher matcher) -> matcher.group("scriptName"),
                  mapping(
                      Function.identity(),
                      collectingAndThen(
                          toList(),
                          list ->
                              list.stream()
                                  .sorted(
                                      Comparator.comparingInt(
                                          matcher ->
                                              Integer.parseInt(matcher.group("chunkNumber"))))
                                  .collect(toList())))));
    } catch (IOException e) {
      throw new IllegalStateException(
          String.format("Error reading path '%s'.", path.toString()), e);
    }
  }

  private static Instant getInstantFromFilenameTimestamp(String timestamp) {
    return ZonedDateTime.of(
            chunkTimestampFormatter.parse(timestamp, LocalDateTime::from), ZoneOffset.UTC)
        .toInstant();
  }

  @Override
// Path: src/java/com/google/cloud/bigquery/dwhassessment/extractiontool/common/ChunkCheckpoint.java
// @AutoValue
// public abstract class ChunkCheckpoint {
// 
//   public abstract Integer lastSavedChunkNumber();
// 
//   public abstract Instant lastSavedInstant();
// 
//   public static Builder builder() {
//     return new AutoValue_ChunkCheckpoint.Builder()
//         .setLastSavedChunkNumber(-1)
//         .setLastSavedInstant(Instant.ofEpochMilli(0));
//   }
// 
//   @AutoValue.Builder
//   public abstract static class Builder {
// 
//     public abstract Builder setLastSavedChunkNumber(Integer value);
// 
//     public abstract Builder setLastSavedInstant(Instant value);
// 
//     public abstract ChunkCheckpoint build();
//   }
// }


// Path: src/java/com/google/cloud/bigquery/dwhassessment/extractiontool/executor/SaveCheckerImpl.java
import static java.util.stream.Collectors.toList;
import static java.util.stream.Collectors.groupingBy;
import static java.util.stream.Collectors.mapping;
import static java.util.stream.Collectors.collectingAndThen;
import com.google.cloud.bigquery.dwhassessment.extractiontool.common.ChunkCheckpoint;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Iterables;
import com.google.re2j.Matcher;
import com.google.re2j.Pattern;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder;
import java.time.format.DateTimeParseException;
import java.util.Comparator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.function.Function;

          .filter(Files::isRegularFile)
          .map(oneFile -> INPUT_CHUNK_PATTERN.matcher(oneFile.getFileName().toString()))
          .filter(Matcher::matches)
          .collect(
              groupingBy(
                  (Matcher matcher) -> matcher.group("scriptName"),
                  mapping(
                      Function.identity(),
                      collectingAndThen(
                          toList(),
                          list ->
                              list.stream()
                                  .sorted(
                                      Comparator.comparingInt(
                                          matcher ->
                                              Integer.parseInt(matcher.group("chunkNumber"))))
                                  .collect(toList())))));
    } catch (IOException e) {
      throw new IllegalStateException(
          String.format("Error reading path '%s'.", path.toString()), e);
    }
  }

  private static Instant getInstantFromFilenameTimestamp(String timestamp) {
    return ZonedDateTime.of(
            chunkTimestampFormatter.parse(timestamp, LocalDateTime::from), ZoneOffset.UTC)
        .toInstant();
  }

  @Override
  public ImmutableMap<String, ChunkCheckpoint> getScriptCheckPoints(Path path) {