/*
 * Copyright 2020 Google LLC.
 *
 * 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.google.cloud.tools.jib.gradle.extension.layerfilter;

import java.util.List;
import javax.inject.Inject;
import org.gradle.api.Action;
import org.gradle.api.Project;
import org.gradle.api.provider.ListProperty;
import org.gradle.api.tasks.Input;
import org.gradle.api.tasks.Nested;
import org.gradle.api.tasks.Optional;

/**
 * Extension-specific Gradle configuration.
 *
 * <p>Example usage in {@code build.gradle}:
 *
 * <pre>{@code
 * configuration {
 *   filters {
 *     filter {
 *       glob = '**&#47;google-*'
 *       toLayer = 'google libraries'
 *     }
 *     filter {
 *       glob = '/app/libs/in-house-*.jar'
 *       toLayer = 'in-house dependencies'
 *     }
 *   }
 * }
 * }</pre>
 */
public class Configuration {

  public static class Filter {
    private String glob = "";
    private String toLayer = "";

    @Input
    public String getGlob() {
      return glob;
    }

    @Input
    @Optional
    public String getToLayer() {
      return toLayer;
    }
  }

  public class FilterSpec {

    /**
     * Adds a new filter configuration to the filters list.
     *
     * @param action closure representing a filter configuration
     */
    public void filter(Action<? super Filter> action) {
      Filter filter = project.getObjects().newInstance(Filter.class);
      action.execute(filter);
      filters.add(filter);
    }
  }

  private final Project project;
  private final FilterSpec filterSpec;
  private final ListProperty<Filter> filters;

  /**
   * Constructor used to inject a Gradle project.
   *
   * @param project the injected Gradle project
   */
  @Inject
  public Configuration(Project project) {
    this.project = project;
    filterSpec = project.getObjects().newInstance(FilterSpec.class);
    filters = project.getObjects().listProperty(Filter.class).empty();
  }

  @Nested
  public List<Filter> getFilters() {
    return filters.get();
  }

  public void filters(Action<? super FilterSpec> action) {
    action.execute(filterSpec);
  }
}

@@ -1498,16 +1498,86 @@
 %0A    %7D%0A%0A
+    public void setGlob(String glob) %7B%0A      this.glob = glob;%0A    %7D%0A%0A
     @Inp
@@ -1649,24 +1649,106 @@
 Layer;%0A    %7D
+%0A%0A    public void setToLayer(String toLayer) %7B%0A      this.toLayer = toLayer;%0A    %7D
 %0A  %7D%0A%0A  publ
@@ -1746,24 +1746,31 @@
 %7D%0A%0A  public 
+static 
 class Filter
@@ -1777,16 +1777,340 @@
 Spec %7B%0A%0A
+    private final Project project;%0A    private final ListProperty%3CFilter%3E filters;%0A%0A    @Inject%0A    public FilterSpec(Project project) %7B%0A      this.project = project;%0A      filters = project.getObjects().listProperty(Filter.class).empty();%0A    %7D%0A%0A    private ListProperty%3CFilter%3E getFilters() %7B%0A      return filters;%0A    %7D%0A%0A
     /**%0A
@@ -2447,41 +2447,8 @@
  %7D%0A%0A
-  private final Project project;%0A
   pr
@@ -2485,54 +2485,8 @@
 pec;
-%0A  private final ListProperty%3CFilter%3E filters;
 %0A%0A  
@@ -2654,36 +2654,8 @@
 ) %7B%0A
-    this.project = project;%0A
     
@@ -2720,79 +2720,17 @@
 lass
-);%0A    filters = project.getObjects().listProperty(Filter.class).empty(
+, project
 );%0A 
@@ -2797,17 +2797,33 @@
 n filter
-s
+Spec.getFilters()
 .get();%0A

Fix Gradle configuration