// Copyright (c) 2016, the R8 project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
package com.android.tools.r8.dex;

import static com.android.tools.r8.dex.Constants.DEX_FILE_MAGIC_PREFIX;

import com.android.tools.r8.ProgramResource;
import com.android.tools.r8.ResourceException;
import com.android.tools.r8.errors.CompilationError;
import com.android.tools.r8.origin.Origin;
import com.android.tools.r8.utils.DexVersion;
import com.android.tools.r8.utils.StringUtils;
import java.io.IOException;
import java.nio.BufferUnderflowException;
import java.nio.ByteOrder;
import java.util.Optional;

/**
 * {@link BinaryReader} for Dex content.
 */
public class DexReader extends BinaryReader {

  private final DexVersion version;

  public DexReader(ProgramResource resource) throws ResourceException, IOException {
    super(resource);
    version = parseMagic(buffer, 0);
  }

  /**
   * Returns a File that contains the bytes provided as argument. Used for testing.
   *
   * @param bytes contents of the file
   */
  DexReader(Origin origin, byte[] bytes) {
    super(origin, bytes);
    version = parseMagic(buffer, 0);
  }

  DexReader(Origin origin, byte[] bytes, int offset) {
    super(origin, bytes);
    version = parseMagic(buffer, offset);
  }

  // Parse the magic header and determine the dex file version.
  private DexVersion parseMagic(CompatByteBuffer buffer, int offset) {
    try {
      buffer.get();
      buffer.rewind();
    } catch (BufferUnderflowException e) {
      throw new CompilationError("Dex file is empty", origin);
    }
    int index = offset;
    for (byte prefixByte : DEX_FILE_MAGIC_PREFIX) {
      byte actualByte = buffer.get(index++);
      if (actualByte != prefixByte) {
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append(
            "Dex file has invalid header, expected "
                + prefixByte
                + " got "
                + actualByte
                + ". Next bytes are ");
        for (int i = 0; i < 10; i++) {
          if (buffer.hasRemaining()) {
            stringBuilder.append(StringUtils.hexString(buffer.get(), 2));
            stringBuilder.append(",");
          }
        }
        throw new CompilationError(stringBuilder.toString(), origin);
      }
    }

    char versionByte0 = (char) buffer.get(index++);
    char versionByte1 = (char) buffer.get(index++);
    char versionByte2 = (char) buffer.get(index++);
    Optional<DexVersion> maybeVersion =
        DexVersion.getDexVersion(versionByte0, versionByte1, versionByte2);
    if (!maybeVersion.isPresent()) {
      throw new CompilationError(
          "Unsupported DEX file version: "
              + versionByte0
              + versionByte1
              + versionByte2,
          origin);
    }
    if (buffer.get(index++) != '\0') {
      throw new CompilationError("Dex file has invalid header", origin);
    }
    return maybeVersion.get();
  }

  @Override
  void setByteOrder() {
    // Make sure we set the right endian for reading.
    buffer.order(ByteOrder.LITTLE_ENDIAN);
    int endian = buffer.getInt(Constants.ENDIAN_TAG_OFFSET);
    if (endian == Constants.REVERSE_ENDIAN_CONSTANT) {
      buffer.order(ByteOrder.BIG_ENDIAN);
    } else {
      if (endian != Constants.ENDIAN_CONSTANT) {
        throw new CompilationError("Unable to determine endianess for reading dex file.");
      }
    }
  }

  DexVersion getDexVersion() {
    return version;
  }
}
