/*
 * Copyright 2012-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.android;

import com.facebook.buck.step.ExecutionContext;
import com.facebook.buck.step.Step;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableSet;
import com.google.common.io.Files;
import com.google.common.io.InputSupplier;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.Enumeration;
import java.util.Set;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;

/**
 * A command that takes a set of JAR files and copies their resources (i.e., "non-.class files")
 * into a directory.
 * <p>
 * This is designed to produce a directory of resources that should be bundled with an APK.
 */
public class ExtractResourcesStep implements Step {

  private final ImmutableSet<String> pathsToThirdPartyJars;
  private final String extractedResourcesDir;

  public ExtractResourcesStep(Set<String> pathsToThirdPartyJars, String extractedResourcesDir) {
    this.pathsToThirdPartyJars = ImmutableSet.copyOf(pathsToThirdPartyJars);
    this.extractedResourcesDir = Preconditions.checkNotNull(extractedResourcesDir);
  }

  @Override
  public int execute(ExecutionContext context) {
    File outputDirectory = new File(extractedResourcesDir);
    for (String path : pathsToThirdPartyJars) {
      try (final JarFile jar = new JarFile(path)) {
        for (Enumeration<JarEntry> entries = jar.entries(); entries.hasMoreElements(); ) {
          final JarEntry entry = entries.nextElement();
          String name = entry.getName();

          // No directories.
          if (entry.isDirectory()) {
            continue;
          }

          // No META-INF nonsense.
          if (name.startsWith("META-INF/")) {
            continue;
          }

          // No .class files.
          if (name.endsWith(".class")) {
            continue;
          }

          // No .java files, either.
          if (name.endsWith(".java")) {
            continue;
          }

          File outputFile = new File(outputDirectory, name);
          Files.createParentDirs(outputFile);
          Files.copy(new InputSupplier<InputStream>() {
            @Override
            public InputStream getInput() throws IOException {
              return jar.getInputStream(entry);
            }
          }, outputFile);
        }
      } catch (IOException e) {
        e.printStackTrace(context.getStdErr());
        return 1;
      }
    }

    return 0;
  }

  @Override
  public String getDescription(ExecutionContext context) {
    return String.format("Extracting resources into %s from the following JARs: %s",
        extractedResourcesDir,
        pathsToThirdPartyJars);
  }

  @Override
  public String getShortName() {
    return "resource_extraction";
  }

}
