// 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.Function;
import com.google.devtools.build.lib.analysis.Runfiles;
import com.google.devtools.build.lib.analysis.TransitiveInfoCollection;
import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable;
import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec;

/**
 * Runfiles provider for C++ targets.
 *
 * <p>Contains two {@link Runfiles} objects: one for the eventual statically linked binary and one
 * for the one that uses shared libraries. Data dependencies are present in both.
 */
@Immutable
@AutoCodec
public final class CcRunfiles {

  private final Runfiles dynamicLibrariesForLinkingStatically;
  private final Runfiles dynamicLibrariesForLinkingDynamically;

  @AutoCodec.Instantiator
  public CcRunfiles(
      Runfiles dynamicLibrariesForLinkingStatically,
      Runfiles dynamicLibrariesForLinkingDynamically) {
    this.dynamicLibrariesForLinkingStatically = dynamicLibrariesForLinkingStatically;
    this.dynamicLibrariesForLinkingDynamically = dynamicLibrariesForLinkingDynamically;
  }

  public Runfiles getDynamicLibrariesForLinkingStatically() {
    return dynamicLibrariesForLinkingStatically;
  }

  public Runfiles getDynamicLibrariesForLinkingDynamically() {
    return dynamicLibrariesForLinkingDynamically;
  }

  /**
   * Returns a function that gets the static C++ runfiles from a {@link TransitiveInfoCollection} or
   * the empty runfiles instance if it does not contain that provider.
   */
  public static final Function<TransitiveInfoCollection, Runfiles>
      DYNAMIC_LIBRARIES_FOR_LINKING_STATICALLY =
          input -> {
            CcLinkingInfo provider = input.get(CcLinkingInfo.PROVIDER);
            CcRunfiles ccRunfiles = provider == null ? null : provider.getCcRunfiles();
            return ccRunfiles == null
                ? Runfiles.EMPTY
                : ccRunfiles.getDynamicLibrariesForLinkingStatically();
          };

  /**
   * Returns a function that gets the shared C++ runfiles from a {@link TransitiveInfoCollection} or
   * the empty runfiles instance if it does not contain that provider.
   */
  public static final Function<TransitiveInfoCollection, Runfiles>
      DYNAMIC_LIBRARIES_FOR_LINKING_DYNAMICALLY =
          input -> {
            CcLinkingInfo provider = input.get(CcLinkingInfo.PROVIDER);
            CcRunfiles ccRunfiles = provider == null ? null : provider.getCcRunfiles();
            return ccRunfiles == null
                ? Runfiles.EMPTY
                : ccRunfiles.getDynamicLibrariesForLinkingDynamically();
          };

  /**
   * Returns a function that gets the C++ runfiles from a {@link TransitiveInfoCollection} or
   * the empty runfiles instance if it does not contain that provider.
   */
  public static final Function<TransitiveInfoCollection, Runfiles> runfilesFunction(
      boolean linkingStatically) {
    return linkingStatically
        ? DYNAMIC_LIBRARIES_FOR_LINKING_STATICALLY
        : DYNAMIC_LIBRARIES_FOR_LINKING_DYNAMICALLY;
  }
}

@@ -1087,17 +1087,8 @@
 the 
-eventual 
 stat
@@ -1119,19 +1119,16 @@
  one
-%0A *
  for the
  one
@@ -1127,78 +1127,112 @@
  the
- one that uses shared libraries. Data dependencies are present in both
+%0A * dynamically linked binary. Both contain dynamic libraries needed at runtime and data%0A * dependencies
 .%0A *
@@ -1309,38 +1309,30 @@
 al Runfiles 
-dynamicLibrari
+runfil
 esForLinking
@@ -1364,38 +1364,30 @@
 al Runfiles 
-dynamicLibrari
+runfil
 esForLinking
@@ -1446,23 +1446,16 @@
 unfiles(
-%0A      
 Runfiles
@@ -1451,38 +1451,30 @@
 es(Runfiles 
-dynamicLibrari
+runfil
 esForLinking
@@ -1484,22 +1484,16 @@
 tically,
-%0A     
  Runfile
@@ -1494,30 +1494,22 @@
 unfiles 
-dynamicLibrari
+runfil
 esForLin
@@ -1532,38 +1532,30 @@
  %7B%0A    this.
-dynamicLibrari
+runfil
 esForLinking
@@ -1563,38 +1563,30 @@
 tatically = 
-dynamicLibrari
+runfil
 esForLinking
@@ -1606,30 +1606,22 @@
    this.
-dynamicLibrari
+runfil
 esForLin
@@ -1638,30 +1638,22 @@
 cally = 
-dynamicLibrari
+runfil
 esForLin
@@ -1691,38 +1691,30 @@
 Runfiles get
-DynamicLibrari
+Runfil
 esForLinking
@@ -1735,38 +1735,30 @@
 %0A    return 
-dynamicLibrari
+runfil
 esForLinking
@@ -1795,30 +1795,22 @@
 iles get
-DynamicLibrari
+Runfil
 esForLin
@@ -1844,22 +1844,14 @@
 urn 
-dynamicLibrari
+runfil
 esFo
@@ -2126,38 +2126,23 @@
 unfiles%3E
-%0A      DYNAMIC_LIBRARI
+ RUNFIL
 ES_FOR_L
@@ -2159,36 +2159,32 @@
 TICALLY =%0A      
-    
 input -%3E %7B%0A     
@@ -2170,36 +2170,32 @@
      input -%3E %7B%0A
-    
         CcLinkin
@@ -2246,36 +2246,32 @@
 VIDER);%0A        
-    
 CcRunfiles ccRun
@@ -2330,36 +2330,32 @@
 iles();%0A        
-    
 return ccRunfile
@@ -2363,32 +2363,16 @@
  == null
-%0A               
  ? Runfi
@@ -2380,32 +2380,16 @@
 es.EMPTY
-%0A               
  : ccRun
@@ -2393,38 +2393,30 @@
 Runfiles.get
-DynamicLibrari
+Runfil
 esForLinking
@@ -2421,36 +2421,32 @@
 ngStatically();%0A
-    
       %7D;%0A%0A  /**%0A
@@ -2696,31 +2696,22 @@
 %3E%0A      
-DYNAMIC_LIBRARI
+RUNFIL
 ES_FOR_L
@@ -3019,22 +3019,14 @@
 .get
-DynamicLibrari
+Runfil
 esFo
@@ -3391,85 +3391,51 @@
 ally
-%0A        ? DYNAMIC_LIBRARIES_FOR_LINKING_STATICALLY%0A        : DYNAMIC_LIBRARI
+ ? RUNFILES_FOR_LINKING_STATICALLY : RUNFIL
 ES_F

Rename CcRunfiles fields one more time to be perfectly accurate.