// 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.analysis;

import static com.google.common.truth.Truth.assertThat;
import static com.google.devtools.build.lib.actions.CompletionContext.FAILED_COMPLETION_CTX;
import static com.google.devtools.build.lib.analysis.TargetCompleteEvent.newFileFromArtifact;
import static java.nio.charset.StandardCharsets.ISO_8859_1;
import static java.nio.charset.StandardCharsets.UTF_8;

import com.google.common.collect.Iterables;
import com.google.devtools.build.lib.actions.Artifact;
import com.google.devtools.build.lib.actions.EventReportingArtifacts.ReportedArtifacts;
import com.google.devtools.build.lib.analysis.TopLevelArtifactHelper.ArtifactsToBuild;
import com.google.devtools.build.lib.analysis.config.BuildConfigurationValue;
import com.google.devtools.build.lib.analysis.util.AnalysisTestCase;
import com.google.devtools.build.lib.buildeventstream.BuildEventStreamProtos.File;
import com.google.devtools.build.lib.collect.nestedset.NestedSet;
import com.google.devtools.build.lib.skyframe.ConfiguredTargetAndData;
import com.google.devtools.build.lib.util.OS;
import com.google.devtools.build.lib.vfs.PathFragment;
import java.util.ArrayList;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

/** Tests for {@link TargetCompleteEvent}. */
@RunWith(JUnit4.class)
public class TargetCompleteEventTest extends AnalysisTestCase {

  /** Regression test for b/165671166. */
  @Test
  public void testFileProtoFromArtifactReencodesAsUtf8() throws Exception {
    if (OS.getCurrent() == OS.WINDOWS) {
      // Windows filesystems return paths with wide characters and don't suffer from the current
      // workaround where arbitrary bytes are represented to Java as Latin-1.
      return;
    }
    scratch.file("sh/BUILD", "filegroup(name = 'globby', srcs = glob(['dir/*']))");
    // Bytes are UTF-8 encoding of: sh/dir/圖片
    byte[] filenameBytes = {
      0x73, 0x68, 0x2f, 0x64, 0x69, 0x72, 0x2f, -27, -100, -106, -25, -119, -121
    };
    String utf8InLatin1FileName = new String(filenameBytes, ISO_8859_1);
    scratch.file(utf8InLatin1FileName, "content does not matter");
    AnalysisResult result = update("//sh:globby");
    ConfiguredTarget ct = Iterables.getOnlyElement(result.getTargetsToBuild());
    TargetAndConfiguration tac = Iterables.getOnlyElement(result.getTopLevelTargetsWithConfigs());
    var configuredTargetConfiguration =
        (BuildConfigurationValue)
            skyframeExecutor.getEvaluator().getExistingValue(ct.getConfigurationKey());
    ConfiguredTargetAndData ctAndData =
        new ConfiguredTargetAndData(ct, tac.getTarget(), configuredTargetConfiguration, null);
    TopLevelArtifactContext context =
        new TopLevelArtifactContext(false, false, false, OutputGroupInfo.DEFAULT_GROUPS);
    ArtifactsToBuild artifactsToBuild = TopLevelArtifactHelper.getAllArtifactsToBuild(ct, context);
    TargetCompleteEvent event =
        TargetCompleteEvent.successfulBuild(
            ctAndData,
            FAILED_COMPLETION_CTX,
            artifactsToBuild.getAllArtifactsByOutputGroup(),
            /*announceTargetSummary=*/ false);

    ArrayList<File> fileProtos = new ArrayList<>();
    ReportedArtifacts reportedArtifacts = event.reportedArtifacts();
    for (NestedSet<Artifact> artifactSet : reportedArtifacts.artifacts) {
      for (Artifact a : artifactSet.toListInterruptibly()) {
        fileProtos.add(
            newFileFromArtifact(
                /* name= */ null,
                a,
                PathFragment.EMPTY_FRAGMENT,
                FAILED_COMPLETION_CTX,
                /* uri= */ null));
      }
    }
    // Bytes are the same but the encoding is actually UTF-8 as required of a protobuf string.
    String utf8FileName = new String(filenameBytes, UTF_8);
    assertThat(fileProtos).hasSize(1);
    assertThat(fileProtos.get(0).getName()).isEqualTo(utf8FileName);
  }
}
