/*
 * 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.google.common.base.Preconditions;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.Charset;
import java.util.Arrays;

/**
 * Helper to create a "canary" class for the secondary DEX. See {@link #create}.
 */
class CanaryFactory {

  private static final String CANARY_PATH_FORMAT = "secondary/dex%02d/Canary.class";

  /**
   * Produced by compiling the following Java file with JDK 7 with "-target 6 -source 6".
   * <pre>
   * package secondary.dex01;
   * public interface Canary {}
   * </pre>
   */
  private static final byte[] CANARY_TEMPLATE = {
      -54,   -2,  -70,  -66, 0x00, 0x00, 0x00, 0x32,
      0x00, 0x05, 0x07, 0x00, 0x03, 0x07, 0x00, 0x04,
      0x01, 0x00, 0x16, 0x73, 0x65, 0x63, 0x6f, 0x6e,
      0x64, 0x61, 0x72, 0x79, 0x2f, 0x64, 0x65, 0x78,
      0x30, 0x31, 0x2f, 0x43, 0x61, 0x6e, 0x61, 0x72,
      0x79, 0x01, 0x00, 0x10, 0x6a, 0x61, 0x76, 0x61,
      0x2f, 0x6c, 0x61, 0x6e, 0x67, 0x2f, 0x4f, 0x62,
      0x6a, 0x65, 0x63, 0x74, 0x06, 0x01, 0x00, 0x01,
      0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00
  };

  /**
   * Offset into {@link #CANARY_TEMPLATE} where we find the 2-byte UTF-8 index that must be
   * updated for each canary class to change the package.
   */
  private static final int CANARY_INDEX_OFFSET = 32;

  /**
   * Adds a "canary" class to a secondary dex that can be safely loaded on any system.
   * This avoids an issue where, during secondary dex loading, we attempt to verify a
   * secondary dex by loading an arbitrary class, but the class we try to load isn't
   * valid on that system (e.g., it depends on Google Maps, but we are on AOSP).
   *
   * @param index Index of the current zip (to ensure unique names).
   */
  static FileLike create(final int index)
      throws IOException {
    final byte[] canaryClass = Arrays.copyOf(CANARY_TEMPLATE, CANARY_TEMPLATE.length);
    final String canaryIndexStr = String.format("%02d", index);
    byte[] canaryIndexBytes = canaryIndexStr.getBytes(Charset.forName("UTF-8"));
    Preconditions.checkState(canaryIndexBytes.length == 2,
        "Formatted index string should always be 2 bytes.");
    System.arraycopy(canaryIndexBytes, 0, canaryClass, CANARY_INDEX_OFFSET, 2);
    String relativePath = String.format(CANARY_PATH_FORMAT, index);
    return getCanaryClass(relativePath, canaryClass);
  }

  private static FileLike getCanaryClass(final String relativePath, final byte[] canaryClass) {
    return new AbstractFileLike() {
      @Override
      public File getContainer() {
        return new File(":memory:");
      }

      @Override
      public String getRelativePath() {
        return relativePath;
      }

      @Override
      public long getSize() {
        return canaryClass.length;
      }

      @Override
      public InputStream getInput() {
        return new ByteArrayInputStream(canaryClass);
      }
    };
  }
}
