/*
 * 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.java.abi;

import static javax.lang.model.SourceVersion.RELEASE_7;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.math.BigInteger;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Collections;
import java.util.Set;
import java.util.SortedSet;
import java.util.TreeSet;

import javax.annotation.processing.AbstractProcessor;
import javax.annotation.processing.RoundEnvironment;
import javax.annotation.processing.SupportedAnnotationTypes;
import javax.annotation.processing.SupportedOptions;
import javax.annotation.processing.SupportedSourceVersion;
import javax.lang.model.element.Element;
import javax.lang.model.element.PackageElement;
import javax.lang.model.element.TypeElement;

@SupportedSourceVersion(RELEASE_7)
@SupportedAnnotationTypes("*")
@SupportedOptions({AbiWriterProtocol.PARAM_ABI_OUTPUT_FILE})
public class AbiWriter extends AbstractProcessor {

  private SortedSet<String> classes = new TreeSet<>();

  @Override
  public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
    RenderableTypes factory = new RenderableTypes();

    for (Element element : roundEnv.getRootElements()) {
      if (element instanceof TypeElement) {
        Renderable renderable = factory.deriveFor(element);
        StringBuilder builder = new StringBuilder();
        renderable.appendTo(builder);
        classes.add(builder.toString());
      } else if (element instanceof PackageElement) {
        // Only found in package-info classes and therefore do not contribute to the ABI.
        continue;
      } else {
        throw new RuntimeException("Unknown type: " + element.getKind());
      }
    }
    String destFile = processingEnv.getOptions().get(AbiWriterProtocol.PARAM_ABI_OUTPUT_FILE);
    if (destFile != null) {
      writeAbi(new File(destFile));
    }

    // We're not laying claim to any annotations.
    return false;
  }

  private void writeAbi(File file) {
    if (!file.getParentFile().exists()) {
      throw new IllegalArgumentException("Directory for ABI key does not exist: " + file);
    }

    if (file.exists() && !file.delete()) {
      throw new IllegalArgumentException("Unable to delete existing ABI key: " + file);
    }

    String key = computeAbiKey();
    try (OutputStream out = new BufferedOutputStream(new FileOutputStream(file))) {
      out.write(key.getBytes());
      out.flush();
    } catch (IOException e) {
      throw new RuntimeException(e);
    }
  }

  public SortedSet<String> getSummaries() {
    return Collections.unmodifiableSortedSet(classes);
  }

  /**
   * Creates a SHA-1 hash from the ABI information extracted by this {@link AbiWriter}.
   */
  public String computeAbiKey() {
    SortedSet<String> summaries = getSummaries();
    return computeAbiKey(summaries);
  }

  static String computeAbiKey(SortedSet<String> summaries) {
    try {
      MessageDigest digest = MessageDigest.getInstance("sha-1");

      for (String summary : summaries) {
        // "2" is the number of bytes in a java character
        ByteBuffer buffer = ByteBuffer.allocate(summary.length() * 2).order(ByteOrder.LITTLE_ENDIAN);

        for (int i = 0; i < summary.length(); i++) {
          buffer.putChar(summary.charAt(i));
        }
        digest.update(buffer.array());
      }
      byte[] sha1Bytes = digest.digest();

      // This isn't a particularly fast operation. A quick test indicates that it's approximately
      // 3-4 times slower than "new BigInteger(1, sha1Bytes).toString(16)". It does, however, ensure
      // that the resulting string is always 40 characters long and padded with 0 if necessary.
      // To give an indication of speed, on my i7 mbp, 100k string generations takes ~450ms compared
      // to ~150ms. In short, the speed hit isn't going to be the end of the world for our use case.
      return String.format("%040x", new BigInteger(1, sha1Bytes));
    } catch (NoSuchAlgorithmException e) {
      // Note: if we get this we're on a broken JRE and we're not having fun.
      throw new RuntimeException(e);
    }
  }
}
