/*
 * Copyright 2015-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.jvm.java;

import com.facebook.buck.rules.AddToRuleKey;
import com.facebook.buck.rules.SourcePath;
import com.facebook.buck.rules.SourcePathResolver;
import com.facebook.buck.util.ClassLoaderCache;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.collect.ImmutableSortedSet;
import com.google.common.collect.Ordering;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.file.Path;
import java.util.function.Function;
import javax.tools.JavaCompiler;

public class JarBackedJavac extends Jsr199Javac {

  private static final Function<Path, URL> PATH_TO_URL =
      p -> {
        try {
          return p.toUri().toURL();
        } catch (MalformedURLException e) {
          throw new RuntimeException(e);
        }
      };

  @AddToRuleKey private final String compilerClassName;
  @AddToRuleKey private final ImmutableSortedSet<SourcePath> classpath;

  public JarBackedJavac(String compilerClassName, Iterable<SourcePath> classpath) {
    this.compilerClassName = compilerClassName;
    this.classpath = ImmutableSortedSet.copyOf(classpath);
  }

  @Override
  protected JavaCompiler createCompiler(
      JavacExecutionContext context, SourcePathResolver resolver) {
    ClassLoaderCache classLoaderCache = context.getClassLoaderCache();
    ClassLoader compilerClassLoader =
        classLoaderCache.getClassLoaderForClassPath(
            ClassLoader.getSystemClassLoader(),
            resolver
                .getAllAbsolutePaths(classpath)
                .stream()
                .map(PATH_TO_URL)
                // Use "toString" since URL.equals does DNS lookups.
                .collect(ImmutableSortedSet.toImmutableSortedSet(Ordering.usingToString()))
                .asList());
    try {
      return (JavaCompiler) compilerClassLoader.loadClass(compilerClassName).newInstance();
    } catch (ClassNotFoundException | IllegalAccessException | InstantiationException ex) {
      throw new RuntimeException(ex);
    }
  }

  @VisibleForTesting
  Iterable<SourcePath> getCompilerClassPath() {
    return classpath;
  }

  @VisibleForTesting
  String getCompilerClassName() {
    return compilerClassName;
  }
}

@@ -1067,44 +1067,8 @@
 th;%0A
-import java.util.function.Function;%0A
 impo
@@ -1151,234 +1151,8 @@
 c %7B%0A
-%0A  private static final Function%3CPath, URL%3E PATH_TO_URL =%0A      p -%3E %7B%0A        try %7B%0A          return p.toUri().toURL();%0A        %7D catch (MalformedURLException e) %7B%0A          throw new RuntimeException(e);%0A        %7D%0A      %7D;%0A%0A
   @A
@@ -1923,19 +1923,33 @@
 map(
-PATH_TO_URL
+JarBackedJavac::pathToUrl
 )%0A  
@@ -2562,11 +2562,182 @@
 ame;%0A  %7D
+%0A%0A  private static URL pathToUrl(Path p) %7B%0A    try %7B%0A      return p.toUri().toURL();%0A    %7D catch (MalformedURLException e) %7B%0A      throw new RuntimeException(e);%0A    %7D%0A  %7D
 %0A%7D%0A

Convert Function to method reference