/*
 * Copyright 2013-present Facebook, 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.facebook.buck.dalvik;

import com.facebook.buck.java.classes.FileLike;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;

import java.io.File;
import java.io.IOException;
import java.util.List;

/**
 * Helper to write to secondary DEX files.
 */
abstract class SecondaryDexHelper<ZIP_OUTPUT_STREAM_HELPER extends ZipOutputStreamHelper> {

  private final File outSecondaryDir;
  private final String secondaryPattern;
  private final ZipSplitter.CanaryStrategy canaryStrategy;

  private int currentSecondaryIndex;
  private ZIP_OUTPUT_STREAM_HELPER currentSecondaryOut;
  private boolean newSecondaryOutOnNextEntry;
  private ImmutableList.Builder<File> secondaryFiles;

  SecondaryDexHelper(
      File outSecondaryDir,
      String secondaryPattern,
      ZipSplitter.CanaryStrategy canaryStrategy) {
    this.outSecondaryDir = Preconditions.checkNotNull(outSecondaryDir);
    this.secondaryPattern = Preconditions.checkNotNull(secondaryPattern);
    this.canaryStrategy = Preconditions.checkNotNull(canaryStrategy);
    this.secondaryFiles = ImmutableList.builder();
  }

  void reset() {
    currentSecondaryIndex = 0;
    currentSecondaryOut = null;
    secondaryFiles = ImmutableList.builder();
  }

  ZIP_OUTPUT_STREAM_HELPER getCurrentOutput() {
    return currentSecondaryOut;
  }

  void finishCurrentZipFile() {
    newSecondaryOutOnNextEntry = true;
  }

  ZIP_OUTPUT_STREAM_HELPER getOutputToWriteTo(FileLike entry) throws IOException {
    // Going to write this entry to a secondary zip.
    if (currentSecondaryOut == null ||
        !currentSecondaryOut.canPutEntry(entry) ||
        newSecondaryOutOnNextEntry) {
      if (currentSecondaryOut != null) {
        currentSecondaryOut.close();
      }
      currentSecondaryIndex++;
      File newSecondaryFile = new File(
          outSecondaryDir,
          String.format(secondaryPattern, currentSecondaryIndex));
      secondaryFiles.add(newSecondaryFile);
      currentSecondaryOut = newZipOutput(newSecondaryFile);
      newSecondaryOutOnNextEntry = false;
      if (canaryStrategy == ZipSplitter.CanaryStrategy.INCLUDE_CANARIES) {
        // Make sure the first class in the new secondary dex can be safely loaded.
        FileLike canaryFile = CanaryFactory.create(currentSecondaryIndex);
        currentSecondaryOut.putEntry(canaryFile);
      }
      // We've already tested for this. It really shouldn't happen.
      Preconditions.checkState(currentSecondaryOut.canPutEntry(entry));
    }

    return currentSecondaryOut;
  }

  void close() throws IOException {
    if (currentSecondaryOut != null) {
      currentSecondaryOut.close();
    }
  }

  List<File> getFiles() {
    return secondaryFiles.build();
  }

  protected abstract ZIP_OUTPUT_STREAM_HELPER newZipOutput(File file) throws IOException;
}
