// Copyright 2017 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.collect.ImmutableList;
import com.google.common.collect.Iterables;
import com.google.devtools.build.lib.actions.ActionExecutionContext;
import com.google.devtools.build.lib.actions.ActionKeyContext;
import com.google.devtools.build.lib.actions.ActionOwner;
import com.google.devtools.build.lib.actions.Artifact;
import com.google.devtools.build.lib.actions.Artifact.ArtifactExpander;
import com.google.devtools.build.lib.analysis.actions.AbstractFileWriteAction;
import com.google.devtools.build.lib.analysis.actions.DeterministicWriter;
import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable;
import com.google.devtools.build.lib.util.Fingerprint;
import com.google.devtools.build.lib.vfs.PathFragment;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import javax.annotation.Nullable;

/**
 * Action for generating an umbrella header. All the headers are #included in the umbrella header.
 */
@Immutable
public final class UmbrellaHeaderAction extends AbstractFileWriteAction {

  private static final String GUID = "62ea2952-bf28-92c3-efb1-e34621646910";

  // NOTE: If you add a field here, you'll likely need to add it to the cache key in computeKey().
  private final Artifact umbrellaHeader;
  private final ImmutableList<Artifact> publicHeaders;
  private final ImmutableList<PathFragment> additionalExportedHeaders;

  public UmbrellaHeaderAction(
      ActionOwner owner,
      Artifact umbrellaHeader,
      Iterable<Artifact> publicHeaders,
      Iterable<PathFragment> additionalExportedHeaders) {
    super(
        owner,
        NestedSetBuilder.<Artifact>stableOrder()
            .addAll(Iterables.filter(publicHeaders, Artifact::isTreeArtifact))
            .build(),
        umbrellaHeader,
        /*makeExecutable=*/ false);
    this.umbrellaHeader = umbrellaHeader;
    this.publicHeaders = ImmutableList.copyOf(publicHeaders);
    this.additionalExportedHeaders = ImmutableList.copyOf(additionalExportedHeaders);
  }

  @Override
  public DeterministicWriter newDeterministicWriter(ActionExecutionContext ctx)  {
    final ArtifactExpander artifactExpander = ctx.getArtifactExpander();
    return new DeterministicWriter() {
      @Override
      public void writeOutputFile(OutputStream out) throws IOException {
        StringBuilder content = new StringBuilder();
        HashSet<PathFragment> deduper = new HashSet<>();
        for (Artifact artifact : expandedHeaders(artifactExpander, publicHeaders)) {
          appendHeader(content, artifact.getExecPath(), deduper);
        }
        for (PathFragment additionalExportedHeader : additionalExportedHeaders) {
          appendHeader(content, additionalExportedHeader, deduper);
        }
        out.write(content.toString().getBytes(StandardCharsets.ISO_8859_1));
      }
    };
  }

  private static Iterable<Artifact> expandedHeaders(ArtifactExpander artifactExpander,
      Iterable<Artifact> unexpandedHeaders) {
    List<Artifact> expandedHeaders = new ArrayList<>();
    for (Artifact unexpandedHeader : unexpandedHeaders) {
      if (unexpandedHeader.isTreeArtifact()) {
        artifactExpander.expand(unexpandedHeader, expandedHeaders);
      } else {
        expandedHeaders.add(unexpandedHeader);
      }
    }
    return ImmutableList.copyOf(expandedHeaders);
  }

  private void appendHeader(StringBuilder content, PathFragment path, 
      HashSet<PathFragment> deduper) {
    if (deduper.contains(path)) {
      return;
    }
    deduper.add(path);
    // #include headers. The #import directive is incompatible with J2ObjC segmented headers.
    content.append("#include \"").append(path).append("\"");
    content.append("\n");
  }
  
  @Override
  public String getMnemonic() {
    return "UmbrellaHeader";
  }

  @Override
  protected void computeKey(
      ActionKeyContext actionKeyContext,
      @Nullable Artifact.ArtifactExpander artifactExpander,
      Fingerprint fp) {
    fp.addString(GUID);
    fp.addPath(umbrellaHeader.getExecPath());
    fp.addInt(publicHeaders.size());
    for (Artifact artifact : publicHeaders) {
      fp.addPath(artifact.getExecPath());
    }
    fp.addInt(additionalExportedHeaders.size());
    for (PathFragment path : additionalExportedHeaders) {
      fp.addPath(path);
    }
  }
}
