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

import com.google.common.base.Splitter;
import com.google.devtools.build.lib.analysis.RuleContext;
import com.google.devtools.build.lib.analysis.actions.FileWriteAction;
import com.google.devtools.build.lib.util.OS;

/**
 * Helper for writing test actions for analysis test rules. Analysis test rules are restricted to
 * disallow the rule implementation functions from registering actions themselves; such rules
 * register test success/failure via {@link AnalysisTestResultInfo}. This helper registers the
 * appropriate test script simulating success or failure of the test.
 */
public class AnalysisTestActionBuilder {

  private AnalysisTestActionBuilder() {}

  /**
   * Register an action to write a test script to the default executable location. The script should
   * return exit status 0 if the test passed. It should print the failure message and return exit
   * status 1 if the test failed.
   */
  public static void writeAnalysisTestAction(
      RuleContext ruleContext, AnalysisTestResultInfo testResultInfo) {
    // TODO(laszlocsomor): Use the execution platform, not the host platform.
    boolean isExecutedOnWindows = OS.getCurrent() == OS.WINDOWS;
    String escapedMessage =
        isExecutedOnWindows
            ? testResultInfo.getMessage().replace("%", "%%")
            // Prefix each character with \ (double-escaped; once in the string, once in the
            // replacement sequence, which allows backslash-escaping literal "$"). "." is put in
            // parentheses because ErrorProne is overly vigorous about objecting to "." as an
            // always-matching regex (b/201772278).
            : testResultInfo.getMessage().replaceAll("(.)", "\\\\$1");
    StringBuilder sb = new StringBuilder();
    if (isExecutedOnWindows) {
      sb.append("@echo off\n");
    }
    for (String line : Splitter.on("\n").split(escapedMessage)) {
      sb.append("echo ").append(line).append("\n");
    }
    sb.append("exit ");
    if (isExecutedOnWindows) {
      sb.append("/b ");
    }
    sb.append(testResultInfo.getSuccess() ? "0" : "1");
    FileWriteAction action =
        FileWriteAction.create(
            ruleContext,
            ruleContext.createOutputArtifactScript(),
            sb.toString(),
            /*makeExecutable=*/ true);
    ruleContext.registerAction(action);
  }
}
