// Copyright 2018 The Bazel Authors. All rights reserved.
//
// 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.devtools.build.lib.rules.android.databinding;

import com.google.common.collect.ImmutableList;
import com.google.devtools.build.lib.actions.Artifact;
import com.google.devtools.build.lib.collect.nestedset.NestedSet;
import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
import com.google.devtools.build.lib.packages.BuiltinProvider;
import com.google.devtools.build.lib.packages.NativeInfo;
import com.google.devtools.build.lib.skylarkbuildapi.android.DataBindingV2ProviderApi;
import com.google.devtools.build.lib.syntax.EvalException;
import com.google.devtools.build.lib.syntax.SkylarkList;
import javax.annotation.Nullable;

/**
 * A provider that exposes this enables <a
 * href="https://developer.android.com/topic/libraries/data-binding/index.html">data binding</a>
 * version 2 on its resource processing and Java compilation.
 */
public final class DataBindingV2Provider extends NativeInfo
    implements DataBindingV2ProviderApi<Artifact> {

  public static final Provider PROVIDER = new Provider();

  private final ImmutableList<Artifact> classInfos;

  private final ImmutableList<Artifact> setterStores;

  private final NestedSet<Artifact> transitiveBRFiles;

  /**
   * The label and java package of this rule and any rules that this rule exports.
   */
  @Nullable
  private final ImmutableList<LabelJavaPackagePair> labelAndJavaPackages;

  private final NestedSet<LabelJavaPackagePair> transitiveLabelAndJavaPackages;

  public DataBindingV2Provider(
      ImmutableList<Artifact> classInfos,
      ImmutableList<Artifact> setterStores,
      NestedSet<Artifact> transitiveBRFiles,
      ImmutableList<LabelJavaPackagePair> labelAndJavaPackages,
      NestedSet<LabelJavaPackagePair> transitiveLabelAndJavaPackages) {
    super(PROVIDER);
    this.classInfos = classInfos;
    this.setterStores = setterStores;
    this.transitiveBRFiles = transitiveBRFiles;
    this.labelAndJavaPackages = labelAndJavaPackages;
    this.transitiveLabelAndJavaPackages = transitiveLabelAndJavaPackages;
  }

  @Override
  public ImmutableList<Artifact> getClassInfos() {
    return classInfos;
  }

  @Override
  public ImmutableList<Artifact> getSetterStores() {
    return setterStores;
  }

  @Override
  public NestedSet<Artifact> getTransitiveBRFiles() {
    return transitiveBRFiles;
  }

  @Override
  @Nullable
  public ImmutableList<LabelJavaPackagePair> getLabelAndJavaPackages() {
    return labelAndJavaPackages;
  }

  @Override
  public NestedSet<LabelJavaPackagePair> getTransitiveLabelAndJavaPackages() {
    return transitiveLabelAndJavaPackages;
  }

  public static DataBindingV2Provider createProvider(
      Artifact setterStoreFile,
      Artifact classInfoFile,
      Artifact brFile,
      String label,
      String javaPackage,
      Iterable<? extends DataBindingV2ProviderApi<Artifact>> databindingV2ProvidersInDeps,
      Iterable<? extends DataBindingV2ProviderApi<Artifact>> databindingV2ProvidersInExports) {

    ImmutableList.Builder<Artifact> setterStoreFiles = ImmutableList.builder();
    if (setterStoreFile != null) {
      setterStoreFiles.add(setterStoreFile);
    }

    ImmutableList.Builder<Artifact> classInfoFiles = ImmutableList.builder();
    if (classInfoFile != null) {
      classInfoFiles.add(classInfoFile);
    }

    NestedSetBuilder<Artifact> brFiles = NestedSetBuilder.stableOrder();
    if (brFile != null) {
      brFiles.add(brFile);
    }

    NestedSetBuilder<LabelJavaPackagePair> transitiveLabelAndJavaPackages =
        NestedSetBuilder.stableOrder();
    ImmutableList.Builder<LabelJavaPackagePair> labelAndJavaPackages = ImmutableList.builder();
    LabelJavaPackagePair labelAndJavaPackage = LabelJavaPackagePair.create(label, javaPackage);
    labelAndJavaPackages.add(labelAndJavaPackage);
    transitiveLabelAndJavaPackages.add(labelAndJavaPackage);

    if (databindingV2ProvidersInDeps != null) {

      for (DataBindingV2ProviderApi<Artifact> provider : databindingV2ProvidersInDeps) {
        brFiles.addTransitive(provider.getTransitiveBRFiles());
        transitiveLabelAndJavaPackages.addTransitive(provider.getTransitiveLabelAndJavaPackages());
      }
    }

    if (databindingV2ProvidersInExports != null) {

      // Add all of the information from providers from exported targets, so that targets which
      // depend on this target appear to depend on the exported targets.
      for (DataBindingV2ProviderApi<Artifact> provider : databindingV2ProvidersInExports) {
        setterStoreFiles.addAll(provider.getSetterStores());
        classInfoFiles.addAll(provider.getClassInfos());
        brFiles.addTransitive(provider.getTransitiveBRFiles());
        labelAndJavaPackages.addAll(provider.getLabelAndJavaPackages());
        transitiveLabelAndJavaPackages.addTransitive(provider.getTransitiveLabelAndJavaPackages());
      }
    }

    return new DataBindingV2Provider(
        classInfoFiles.build(),
        setterStoreFiles.build(),
        brFiles.build(),
        labelAndJavaPackages.build(),
        transitiveLabelAndJavaPackages.build());
  }

  /** The provider can construct the DataBindingV2Provider provider. */
  public static class Provider extends BuiltinProvider<DataBindingV2Provider>
      implements DataBindingV2ProviderApi.Provider<Artifact> {

    private Provider() {
      super(NAME, DataBindingV2Provider.class);
    }

    @Override
    public DataBindingV2ProviderApi<Artifact> createInfo(
        Artifact setterStoreFile,
        Artifact classInfoFile,
        Artifact brFile,
        String label,
        String javaPackage,
        SkylarkList<DataBindingV2ProviderApi<Artifact>> databindingV2ProvidersInDeps,
        SkylarkList<DataBindingV2ProviderApi<Artifact>> databindingV2ProvidersInExports)
        throws EvalException {

      return createProvider(
          setterStoreFile,
          classInfoFile,
          brFile,
          label,
          javaPackage,
          databindingV2ProvidersInDeps == null
              ? null
              : databindingV2ProvidersInDeps.getImmutableList(),
          databindingV2ProvidersInExports == null
              ? null
              : databindingV2ProvidersInExports.getImmutableList());
    }
  }
}
