// Copyright 2014 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.cpp;

import com.google.common.base.Objects;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable;
import com.google.devtools.build.lib.events.Location;
import com.google.devtools.build.lib.packages.NativeInfo;
import com.google.devtools.build.lib.packages.NativeProvider;
import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec;
import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec.VisibleForSerialization;
import com.google.devtools.build.lib.skylarkbuildapi.cpp.CcLinkingInfoApi;
import com.google.devtools.build.lib.syntax.Environment;
import com.google.devtools.build.lib.syntax.EvalException;
import com.google.devtools.build.lib.syntax.FunctionSignature;
import com.google.devtools.build.lib.syntax.Runtime;
import com.google.devtools.build.lib.syntax.SkylarkType;
import java.util.Collection;
import javax.annotation.Nullable;

/** Wrapper for every C++ linking provider. */
@Immutable
@AutoCodec
public final class CcLinkingInfo extends NativeInfo implements CcLinkingInfoApi {

  private static final FunctionSignature.WithValues<Object, SkylarkType> SIGNATURE =
      FunctionSignature.WithValues.create(
          FunctionSignature.of(
              /* numMandatoryPositionals= */ 0,
              /* numOptionalPositionals= */ 0,
              // TODO(plf): Make CcLinkParams parameters mandatory once existing rules have been
              // migrated.
              /* numMandatoryNamedOnly= */ 0,
              /* starArg= */ false,
              /* kwArg= */ false,
              "static_mode_params_for_dynamic_library",
              "static_mode_params_for_executable",
              "dynamic_mode_params_for_dynamic_library",
              "dynamic_mode_params_for_executable"),
          /* defaultValues= */ ImmutableList.of(
              Runtime.NONE, Runtime.NONE, Runtime.NONE, Runtime.NONE),
          /* types= */ ImmutableList.of(
              SkylarkType.of(CcLinkParams.class),
              SkylarkType.of(CcLinkParams.class),
              SkylarkType.of(CcLinkParams.class),
              SkylarkType.of(CcLinkParams.class)));

  @Nullable
  private static Object nullIfNone(Object object) {
    return nullIfNone(object, Object.class);
  }

  @Nullable
  private static <T> T nullIfNone(Object object, Class<T> type) {
    return object != Runtime.NONE ? type.cast(object) : null;
  }

  public static final NativeProvider<CcLinkingInfo> PROVIDER =
      new NativeProvider<CcLinkingInfo>(CcLinkingInfo.class, "CcLinkingInfo", SIGNATURE) {
        @Override
        @SuppressWarnings("unchecked")
        protected CcLinkingInfo createInstanceFromSkylark(
            Object[] args, Environment env, Location loc) throws EvalException {
          CcCommon.checkLocationWhitelisted(
              env.getSemantics(),
              loc,
              env.getGlobals().getTransitiveLabel().getPackageIdentifier().toString());
          int i = 0;
          CcLinkParams staticModeParamsForDynamicLibrary = (CcLinkParams) nullIfNone(args[i++]);
          CcLinkParams staticModeParamsForExecutable = (CcLinkParams) nullIfNone(args[i++]);
          CcLinkParams dynamicModeParamsForDynamicLibrary = (CcLinkParams) nullIfNone(args[i++]);
          CcLinkParams dynamicModeParamsForExecutable = (CcLinkParams) nullIfNone(args[i++]);
          CcLinkingInfo.Builder ccLinkingInfoBuilder = CcLinkingInfo.Builder.create();
          if (staticModeParamsForDynamicLibrary == null
              || staticModeParamsForExecutable == null
              || dynamicModeParamsForDynamicLibrary == null
              || dynamicModeParamsForExecutable == null) {
            throw new EvalException(
                loc, "Every CcLinkParams parameter must be passed to CcLinkingInfo.");
          }
          ccLinkingInfoBuilder
              .setStaticModeParamsForDynamicLibrary(staticModeParamsForDynamicLibrary)
              .setStaticModeParamsForExecutable(staticModeParamsForExecutable)
              .setDynamicModeParamsForDynamicLibrary(dynamicModeParamsForDynamicLibrary)
              .setDynamicModeParamsForExecutable(dynamicModeParamsForExecutable);
          return ccLinkingInfoBuilder.build();
        }
      };

  public static final CcLinkingInfo EMPTY =
      CcLinkingInfo.Builder.create()
          .setStaticModeParamsForDynamicLibrary(CcLinkParams.EMPTY)
          .setStaticModeParamsForExecutable(CcLinkParams.EMPTY)
          .setDynamicModeParamsForDynamicLibrary(CcLinkParams.EMPTY)
          .setDynamicModeParamsForExecutable(CcLinkParams.EMPTY)
          .build();

  private final CcLinkParams staticModeParamsForExecutable;
  private final CcLinkParams staticModeParamsForDynamicLibrary;
  private final CcLinkParams dynamicModeParamsForExecutable;
  private final CcLinkParams dynamicModeParamsForDynamicLibrary;

  @AutoCodec.Instantiator
  @VisibleForSerialization
  CcLinkingInfo(
      CcLinkParams staticModeParamsForExecutable,
      CcLinkParams staticModeParamsForDynamicLibrary,
      CcLinkParams dynamicModeParamsForExecutable,
      CcLinkParams dynamicModeParamsForDynamicLibrary) {
    super(PROVIDER);
    this.staticModeParamsForExecutable = staticModeParamsForExecutable;
    this.staticModeParamsForDynamicLibrary = staticModeParamsForDynamicLibrary;
    this.dynamicModeParamsForExecutable = dynamicModeParamsForExecutable;
    this.dynamicModeParamsForDynamicLibrary = dynamicModeParamsForDynamicLibrary;
  }

  @Override
  public CcLinkParams getStaticModeParamsForExecutable() {
    return staticModeParamsForExecutable;
  }

  @Override
  public CcLinkParams getStaticModeParamsForDynamicLibrary() {
    return staticModeParamsForDynamicLibrary;
  }

  @Override
  public CcLinkParams getDynamicModeParamsForExecutable() {
    return dynamicModeParamsForExecutable;
  }

  @Override
  public CcLinkParams getDynamicModeParamsForDynamicLibrary() {
    return dynamicModeParamsForDynamicLibrary;
  }

  public static CcLinkingInfo merge(Collection<CcLinkingInfo> ccLinkingInfos) {
    CcLinkParams.Builder staticModeParamsForDynamicLibraryBuilder = CcLinkParams.builder();
    CcLinkParams.Builder staticModeParamsForExecutableBuilder = CcLinkParams.builder();
    CcLinkParams.Builder dynamicModeParamsForDynamicLibraryBuilder = CcLinkParams.builder();
    CcLinkParams.Builder dynamicModeParamsForExecutableBuilder = CcLinkParams.builder();
    for (CcLinkingInfo ccLinkingInfo : ccLinkingInfos) {
      staticModeParamsForDynamicLibraryBuilder.addTransitiveArgs(
          ccLinkingInfo.getStaticModeParamsForDynamicLibrary());
      staticModeParamsForExecutableBuilder.addTransitiveArgs(
          ccLinkingInfo.getStaticModeParamsForExecutable());
      dynamicModeParamsForDynamicLibraryBuilder.addTransitiveArgs(
          ccLinkingInfo.getDynamicModeParamsForDynamicLibrary());
      dynamicModeParamsForExecutableBuilder.addTransitiveArgs(
          ccLinkingInfo.getDynamicModeParamsForExecutable());
    }
    return new CcLinkingInfo.Builder()
        .setStaticModeParamsForDynamicLibrary(staticModeParamsForDynamicLibraryBuilder.build())
        .setStaticModeParamsForExecutable(staticModeParamsForExecutableBuilder.build())
        .setDynamicModeParamsForDynamicLibrary(dynamicModeParamsForDynamicLibraryBuilder.build())
        .setDynamicModeParamsForExecutable(dynamicModeParamsForExecutableBuilder.build())
        .build();
  }

  public CcLinkParams getCcLinkParams(boolean staticMode, boolean forDynamicLibrary) {
    if (staticMode) {
      if (forDynamicLibrary) {
        return getStaticModeParamsForDynamicLibrary();
      } else {
        return getStaticModeParamsForExecutable();
      }
    } else {
      if (forDynamicLibrary) {
        return getDynamicModeParamsForDynamicLibrary();
      } else {
        return getDynamicModeParamsForExecutable();
      }
    }
  }

  /** A Builder for {@link CcLinkingInfo}. */
  public static class Builder {
    CcLinkParams staticModeParamsForDynamicLibrary;
    CcLinkParams staticModeParamsForExecutable;
    CcLinkParams dynamicModeParamsForDynamicLibrary;
    CcLinkParams dynamicModeParamsForExecutable;

    public static CcLinkingInfo.Builder create() {
      return new CcLinkingInfo.Builder();
    }

    public Builder setStaticModeParamsForDynamicLibrary(CcLinkParams ccLinkParams) {
      Preconditions.checkState(this.staticModeParamsForDynamicLibrary == null);
      this.staticModeParamsForDynamicLibrary = ccLinkParams;
      return this;
    }

    public Builder setStaticModeParamsForExecutable(CcLinkParams ccLinkParams) {
      Preconditions.checkState(this.staticModeParamsForExecutable == null);
      this.staticModeParamsForExecutable = ccLinkParams;
      return this;
    }

    public Builder setDynamicModeParamsForDynamicLibrary(CcLinkParams ccLinkParams) {
      Preconditions.checkState(this.dynamicModeParamsForDynamicLibrary == null);
      this.dynamicModeParamsForDynamicLibrary = ccLinkParams;
      return this;
    }

    public Builder setDynamicModeParamsForExecutable(CcLinkParams ccLinkParams) {
      Preconditions.checkState(this.dynamicModeParamsForExecutable == null);
      this.dynamicModeParamsForExecutable = ccLinkParams;
      return this;
    }

    public CcLinkingInfo build() {
      Preconditions.checkNotNull(staticModeParamsForExecutable);
      Preconditions.checkNotNull(staticModeParamsForDynamicLibrary);
      Preconditions.checkNotNull(dynamicModeParamsForExecutable);
      Preconditions.checkNotNull(dynamicModeParamsForDynamicLibrary);
      return new CcLinkingInfo(
          staticModeParamsForExecutable,
          staticModeParamsForDynamicLibrary,
          dynamicModeParamsForExecutable,
          dynamicModeParamsForDynamicLibrary);
    }
  }

  @Override
  public boolean equals(Object otherObject) {
    if (!(otherObject instanceof CcLinkingInfo)) {
      return false;
    }
    CcLinkingInfo other = (CcLinkingInfo) otherObject;
    if (this == other) {
      return true;
    }
    if (!this.staticModeParamsForExecutable.equals(other.staticModeParamsForExecutable)
        || !this.staticModeParamsForDynamicLibrary.equals(other.staticModeParamsForDynamicLibrary)
        || !this.dynamicModeParamsForExecutable.equals(other.dynamicModeParamsForExecutable)
        || !this.dynamicModeParamsForDynamicLibrary.equals(
            other.dynamicModeParamsForDynamicLibrary)) {
      return false;
    }
    return true;
  }

  @Override
  public int hashCode() {
    return Objects.hashCode(
        staticModeParamsForExecutable,
        staticModeParamsForDynamicLibrary,
        dynamicModeParamsForExecutable,
        dynamicModeParamsForDynamicLibrary);
  }
}
