/*
 * Copyright (C) 2013 The Android Open Source Project
 *
 * 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.android.jill.frontend.java;

import com.android.jill.ContainerType;
import com.android.jill.JillException;
import com.android.jill.Options;
import com.android.jill.backend.jayce.JayceWriter;
import com.android.jill.utils.FileUtils;

import org.objectweb.asm.ClassReader;
import org.objectweb.asm.tree.ClassNode;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Enumeration;
import java.util.List;
import java.util.Properties;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

import javax.annotation.CheckForNull;
import javax.annotation.Nonnull;

/**
 * Transforms java binary files into jayce.
 */
public class JavaTransformer {

  @Nonnull
  private static final String LIB_MAJOR_VERSION = "2";

  @Nonnull
  private static final String LIB_MINOR_VERSION = "2";

  @Nonnull
  private static final String JAYCE_MAJOR_VERSION = "3";

  @Nonnull
  private static final String JAYCE_MINOR_VERSION = "5";

  @Nonnull
  private static final String KEY_LIB_MAJOR_VERSION = "lib.version.major";

  @Nonnull
  private static final String KEY_LIB_MINOR_VERSION = "lib.version.minor";

  @Nonnull
  private static final String KEY_LIB_EMITTER = "lib.emitter";

  @Nonnull
  private static final String KEY_LIB_EMITTER_VERSION = "lib.emitter.version";

  @Nonnull
  private static final String KEY_JAYCE = "jayce";

  @Nonnull
  private static final String KEY_JAYCE_MAJOR_VERSION = "jayce.version.major";

  @Nonnull
  private static final String KEY_JAYCE_MINOR_VERSION = "jayce.version.minor";

  @Nonnull
  private static final String JACK_LIBRARY_PROPERTIES = "jack.properties";

  @Nonnull
  private final String version;

  private final Options options;

  @Nonnull
  private static final String JAYCE_FILE_EXTENSION = ".jayce";

  @Nonnull
  private static final String JAYCE_PREFIX_INTO_LIB = "jayce";

  @Nonnull
  private static final char TYPE_NAME_SEPARATOR = '/';

  @Nonnull
  private final Properties jackLibraryProperties;

  public JavaTransformer(@Nonnull String version, @Nonnull Options options) {
    this.version = version;
    this.options = options;
    jackLibraryProperties = new Properties();
    jackLibraryProperties.put(KEY_LIB_EMITTER, "jill");
    jackLibraryProperties.put(KEY_LIB_EMITTER_VERSION, version);
    jackLibraryProperties.put(KEY_LIB_MAJOR_VERSION, LIB_MAJOR_VERSION);
    jackLibraryProperties.put(KEY_LIB_MINOR_VERSION, LIB_MINOR_VERSION);
  }

  public void transform(@Nonnull List<File> javaBinaryFiles) {
    ZipOutputStream zos = null;
    try {
      if (options.getOutputContainer() == ContainerType.ZIP) {
        zos = new ZipOutputStream(new FileOutputStream(options.getOutput()));
        for (File fileToTransform : javaBinaryFiles) {
          InputStream is = new BufferedInputStream(new FileInputStream(fileToTransform));
          try {
            transformToZip(is, zos, null);
          } finally {
            is.close();
          }
        }
      } else {
        for (File fileToTransform : javaBinaryFiles) {
          FileInputStream fis = new FileInputStream(fileToTransform);
          try {
            transformToDir(fis, options.getOutput());
          } finally {
            fis.close();
          }
        }
      }
      dumpJackLibraryProperties(zos);
    } catch (IOException e) {
      throw new JillException("Transformation failure.", e);
    } finally {
      if (zos != null) {
        try {
          zos.close();
        } catch (IOException e) {
          throw new JillException("Error closing zip.", e);
        }
      }
    }
  }

  public void transform(@Nonnull JarFile jarFile) {
    ZipOutputStream zos = null;
    try {
      if (options.getOutputContainer() == ContainerType.ZIP) {
        zos = new ZipOutputStream(new FileOutputStream(options.getOutput()));
      }
      transformJavaFiles(jarFile, zos);
      dumpJackLibraryProperties(zos);
    } catch (JillException e) {
      throw e;
    } catch (Exception e) {
      throw new JillException(e.getMessage(), e);
    } finally {
      if (zos != null) {
        try {
          zos.close();
        } catch (IOException e) {
          throw new JillException("Error closing zip.", e);
        }
      }
    }
  }

  private void dumpJackLibraryProperties(@CheckForNull ZipOutputStream zos) {
    if (zos != null) {
      dumpPropertiesToZip(zos, jackLibraryProperties);
    } else {
      dumpPropertiesToFile(new File(options.getOutput(), JACK_LIBRARY_PROPERTIES),
          jackLibraryProperties);
    }
  }

  private void dumpPropertiesToZip(@Nonnull ZipOutputStream zos,
      @Nonnull Properties libraryProperties) {
    try {
      ZipEntry entry = new ZipEntry(JACK_LIBRARY_PROPERTIES);
      zos.putNextEntry(entry);
      libraryProperties.store(zos, "Library Properties");
    } catch (IOException e) {
      throw new JillException("Error writing '" + JACK_LIBRARY_PROPERTIES + "' to output zip", e);
    }
  }

  private void dumpPropertiesToFile(@Nonnull File outputFile,
      @Nonnull Properties libraryProperties) {
    File outputDir = options.getOutput();
    File libraryPropertiesFile = new File(outputDir, JACK_LIBRARY_PROPERTIES);
    FileOutputStream fos = null;
    try {
      fos = new FileOutputStream(libraryPropertiesFile);
      libraryProperties.store(fos, "Library Properties");
    } catch (IOException e) {
      throw new JillException(
          "Error writing '" + JACK_LIBRARY_PROPERTIES + "' to " + outputFile.getAbsolutePath(), e);
    } finally {
      if (fos != null) {
        try {
          fos.close();
        } catch (IOException e) {
          throw new JillException("Error closing output " + outputFile.getAbsolutePath(), e);
        }
      }
    }
  }

  private void transformJavaFiles(@Nonnull JarFile jarFile, @CheckForNull ZipOutputStream zos)
      throws IOException {
    final Enumeration<JarEntry> entries = jarFile.entries();
    while (entries.hasMoreElements()) {
      final JarEntry entry = entries.nextElement();
      String name = entry.getName();
      if (FileUtils.isJavaBinaryFile(name)) {
        JarEntry fileEntry = jarFile.getJarEntry(name);
        if (!fileEntry.isDirectory()) {
          InputStream is = jarFile.getInputStream(fileEntry);
          if (zos != null) {
            assert options.getOutputContainer() == ContainerType.ZIP;
            transformToZip(is, zos, jarFile);
          } else {
            assert options.getOutputContainer() == ContainerType.DIR;
            transformToDir(is, options.getOutput());
          }
        }
      }
    }
  }

  private void transformToZip(@Nonnull InputStream is, @Nonnull ZipOutputStream zipOutputStream,
      @CheckForNull JarFile jarFile) throws IOException {
    ClassNode cn = getClassNode(is);
    String filePath = getZipFilePath(cn.name);
    assert (jarFile == null || jarFile.getEntry(filePath) == null);
    try {
      ZipEntry entry = new ZipEntry(filePath);
      zipOutputStream.putNextEntry(entry);
      transform(cn, zipOutputStream);
    } catch (IOException e) {
      throw new JillException("Error writing to output zip", e);
    }
  }

  private void transformToDir(@Nonnull InputStream is, @Nonnull File outputDir)
      throws IOException {
    ClassNode cn = getClassNode(is);
    String filePath = getFilePath(cn.name);

    File outputFile = new File(outputDir, filePath);
    assert !outputFile.exists();
    FileOutputStream fos = null;
    try {
      createParentDirectories(outputFile);
      fos = new FileOutputStream(outputFile);
      transform(cn, fos);
    } catch (IOException e) {
      throw new JillException("Unable to create output file " + outputFile.getName(), e);
    } finally {
      if (fos != null) {
        try {
          fos.close();
        } catch (IOException e) {
          throw new JillException("Error closing output " + outputFile.getAbsolutePath(), e);
        }
      }
    }
  }

  private void transform(@Nonnull ClassNode cn, @Nonnull OutputStream os) throws IOException {

    JayceWriter writer = createWriter(os);

    ClassNodeWriter asm2jayce =
        new ClassNodeWriter(writer, new SourceInfoWriter(writer), options);

    asm2jayce.write(cn);

    writer.flush();
  }

  private void createParentDirectories(File outputFile) throws IOException {
    File parentFile = outputFile.getParentFile();
    if (!parentFile.exists() && !parentFile.mkdirs()) {
      throw new IOException("Could not create directory \"" + parentFile.getName() + "\"");
    }
  }

  private JayceWriter createWriter(@Nonnull OutputStream os) {
    JayceWriter writer = new JayceWriter(os);
    setJayceProperties();
    return writer;
  }

  @Nonnull
  private static String getFilePath(@Nonnull String typeBinaryName) {
    return JAYCE_PREFIX_INTO_LIB + File.separatorChar
        + typeBinaryName.replace(TYPE_NAME_SEPARATOR, File.separatorChar) + JAYCE_FILE_EXTENSION;
  }

  @Nonnull
  private static String getZipFilePath(@Nonnull String typeBinaryName) {
    return JAYCE_PREFIX_INTO_LIB + '/'
        + typeBinaryName.replace(TYPE_NAME_SEPARATOR, '/') + JAYCE_FILE_EXTENSION;
  }

  @Nonnull
  private ClassNode getClassNode(@Nonnull InputStream is) throws IOException {
    try {
      ClassReader cr = new ClassReader(is);
      ClassNode cn = new ClassNode();
      cr.accept(cn,
          ClassReader.SKIP_FRAMES | (options.isEmitDebugInfo() ? 0 : ClassReader.SKIP_DEBUG));
      return cn;
    } catch (IllegalArgumentException e) {
      // It means that class files come from an unsupported Java version
      throw new JillException("class files coming from an unsupported Java version", e);
    }
  }

  private void setJayceProperties() {
    jackLibraryProperties.put(KEY_JAYCE, String.valueOf(true));
    jackLibraryProperties.put(KEY_JAYCE_MAJOR_VERSION, JAYCE_MAJOR_VERSION);
    jackLibraryProperties.put(KEY_JAYCE_MINOR_VERSION, JAYCE_MINOR_VERSION);
  }
}
