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

#include "src/main/cpp/blaze_util.h"

#include <fcntl.h>
#include <signal.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <algorithm>
#include <cassert>
#include <iostream>

#include "src/main/cpp/blaze_util_platform.h"
#include "src/main/cpp/util/errors.h"
#include "src/main/cpp/util/exit_code.h"
#include "src/main/cpp/util/file.h"
#include "src/main/cpp/util/logging.h"
#include "src/main/cpp/util/numbers.h"
#include "src/main/cpp/util/path_platform.h"
#include "src/main/cpp/util/port.h"
#include "src/main/cpp/util/strings.h"
#include "absl/base/log_severity.h"
#include "absl/log/globals.h"
#include "absl/log/initialize.h"

namespace blaze {

using std::map;
using std::string;
using std::vector;

const char kServerPidFile[] = "server.pid.txt";

const unsigned int kPostShutdownGracePeriodSeconds = 60;

const unsigned int kPostKillGracePeriodSeconds = 10;

const char* GetUnaryOption(const char* arg, const char* next_arg,
                           const char* key) {
  const char* value = blaze_util::var_strprefix(arg, key);
  if (value == nullptr) {
    return nullptr;
  } else if (value[0] == '=') {
    return value + 1;
  } else if (value[0]) {
    return nullptr;  // trailing garbage in key name
  }

  return next_arg;
}

bool GetNullaryOption(const char* arg, const char* key) {
  const char* value = blaze_util::var_strprefix(arg, key);
  if (value == nullptr) {
    return false;
  } else if (value[0] == '=') {
    BAZEL_DIE(blaze_exit_code::BAD_ARGV)
        << "In argument '" << arg << "': option '" << key
        << "' does not take a value.";
  } else if (value[0]) {
    return false;  // trailing garbage in key name
  }

  return true;
}

std::vector<std::string> GetAllUnaryOptionValues(
    const vector<string>& args, const char* key,
    const char* ignore_after_value) {
  vector<std::string> values;
  for (vector<string>::size_type i = 0; i < args.size(); ++i) {
    if (args[i] == "--") {
      // "--" means all remaining args aren't options
      return values;
    }

    const char* next_arg = args[std::min(i + 1, args.size() - 1)].c_str();
    const char* result = GetUnaryOption(args[i].c_str(), next_arg, key);
    if (result != nullptr) {
      // 'key' was found and 'result' has its value.
      values.push_back(result);

      if (ignore_after_value != nullptr &&
          strcmp(result, ignore_after_value) == 0) {
        break;
      }
    }

    // This is a pointer comparison, so equality means that the result must be
    // from the next arg instead of happening to match the value from
    // "--key=<value>" string, in which case we need to advance the index to
    // skip the next arg for later iterations.
    if (result == next_arg) {
      i++;
    }
  }

  return values;
}

bool SearchNullaryOption(const vector<string>& args, const string& flag_name,
                         const bool default_value) {
  const string positive_flag = "--" + flag_name;
  const string negative_flag = "--no" + flag_name;
  bool result = default_value;
  for (vector<string>::size_type i = 0; i < args.size(); i++) {
    if (args[i] == "--") {
      break;
    }
    if (GetNullaryOption(args[i].c_str(), positive_flag.c_str())) {
      result = true;
    } else if (GetNullaryOption(args[i].c_str(), negative_flag.c_str())) {
      result = false;
    }
  }
  return result;
}

bool IsArg(const string& arg) {
  return blaze_util::starts_with(arg, "-") && (arg != "--help") &&
         (arg != "-help") && (arg != "-h");
}

std::string AbsolutePathFromFlag(const std::string& value) {
  if (value.empty()) {
    return blaze_util::GetCwd();
  } else if (!value.empty() && value[0] == '~') {
    return blaze_util::JoinPath(GetHomeDir(), value.substr(1));
  } else {
    return blaze_util::MakeAbsolute(value);
  }
}

void LogWait(unsigned int elapsed_seconds, unsigned int wait_seconds,
             TerminationReason reason) {
  const char* reason_str = nullptr;
  switch (reason) {
    case TerminationReason::kShutdownRequest:
      reason_str = "after shutdown request";
      break;
    case TerminationReason::kKillSignal:
      reason_str = "after SIGKILL";
      break;
    case TerminationReason::kUnspecified:
      break;
  }
  if (reason_str != nullptr) {
    SigPrintf(
        "WARNING: Waiting for server process to terminate "
        "(waited %d seconds, waiting at most %d; %s)\n",
        elapsed_seconds, wait_seconds, reason_str);
  } else {
    SigPrintf(
        "WARNING: Waiting for server process to terminate "
        "(waited %d seconds, waiting at most %d)\n",
        elapsed_seconds, wait_seconds);
  }
}

// Install a signal handler and restore the previous handler after the scope
// ends.
class SignalHandlerGuard {
 public:
  SignalHandlerGuard(int sig, void (*handler)(int)) {
    sig_ = sig;
    previous_handler_ = signal(sig, handler);
  }

  ~SignalHandlerGuard() { signal(sig_, previous_handler_); }

 private:
  int sig_;
  void (*previous_handler_)(int);
};

static volatile bool interrupted_during_await_termination;

static void SignalHandlerDuringAwaitTermination(int signal) {
  interrupted_during_await_termination = true;
}

bool AwaitServerProcessTermination(int pid, const blaze_util::Path& output_base,
                                   unsigned int wait_seconds,
                                   TerminationReason reason) {
  uint64_t st = GetMillisecondsMonotonic();
  const unsigned int first_seconds = 5;
  bool logged_first = false;
  const unsigned int second_seconds = 10;
  bool logged_second = false;
  const unsigned int third_seconds = 30;
  bool logged_third = false;

  // b/428029833: Install signal handlers to make sure the server process is
  // killed upon interruption.
  interrupted_during_await_termination = false;
  SignalHandlerGuard sigint_handler_guard(SIGINT,
                                          SignalHandlerDuringAwaitTermination);
  SignalHandlerGuard sigterm_handler_guard(SIGTERM,
                                           SignalHandlerDuringAwaitTermination);
#ifndef _WIN32  // SIGQUIT is not supported on Windows.
  SignalHandlerGuard sigquit_handler_guard(SIGQUIT,
                                           SignalHandlerDuringAwaitTermination);
#endif

  while (VerifyServerProcess(pid, output_base)) {
    if (interrupted_during_await_termination) {
      return false;
    }
    TrySleep(100);
    uint64_t elapsed_millis = GetMillisecondsMonotonic() - st;
    if (!logged_first && elapsed_millis > first_seconds * 1000) {
      LogWait(first_seconds, wait_seconds, reason);
      logged_first = true;
    }
    if (!logged_second && elapsed_millis > second_seconds * 1000) {
      LogWait(second_seconds, wait_seconds, reason);
      logged_second = true;
    }
    if (!logged_third && elapsed_millis > third_seconds * 1000) {
      LogWait(third_seconds, wait_seconds, reason);
      logged_third = true;
    }
    if (elapsed_millis > wait_seconds * 1000) {
      SigPrintf(
          "INFO: Waited %d seconds for server process (pid=%d) to"
          " terminate.\n",
          wait_seconds, pid);
      return false;
    }
  }
  return true;
}

void SetDebugLog(blaze_util::LoggingDetail detail) {
  if (detail == blaze_util::LOGGINGDETAIL_DEBUG) {
    blaze_util::SetLoggingDetail(blaze_util::LOGGINGDETAIL_DEBUG, &std::cerr);
    absl::SetStderrThreshold(absl::LogSeverityAtLeast::kInfo);
  } else {
    blaze_util::SetLoggingDetail(detail, nullptr);

    // Disable absl debug logging, since that gets printed to stderr due to us
    // not setting up a log file. We don't use absl but one of our dependencies
    // might (as of 2024Q2, gRPC does).
    //
    // Future improvements to this approach:
    // * Disable absl logging ASAP, not just here after handling
    //   --client_debug=false.
    // * Use the same approach for handling --client_debug=true that we do for
    //   BAZEL_LOG of first redirecting all messages to an inmemory string, and
    //   then writing that string to stderr. We could use a absl::LogSink to
    //   achieve this.
    absl::InitializeLog();
    absl::SetStderrThreshold(absl::LogSeverityAtLeast::kInfinity);
  }
}

bool IsRunningWithinTest() { return ExistsEnv("TEST_TMPDIR"); }

blaze_util::Path GetOOMFilePath(const blaze_util::Path& output_base) {
  return output_base.GetRelative("blaze_oomed");
}

blaze_util::Path GetAbruptExitFilePath(const blaze_util::Path& output_base) {
  // It would make more sense for this file to be in the "server" subdirectory,
  // but changing that would require migrating invokers of Blaze.
  return output_base.GetRelative("exit_code_to_use_on_abrupt_exit");
}

void WithEnvVars::SetEnvVars(const map<string, EnvVarValue>& vars) {
  for (const auto& var : vars) {
    switch (var.second.action) {
      case EnvVarAction::UNSET:
        UnsetEnv(var.first);
        break;

      case EnvVarAction::SET:
        SetEnv(var.first, var.second.value);
        break;

      default:
        assert(false);
    }
  }
}

WithEnvVars::WithEnvVars(const map<string, EnvVarValue>& vars) {
  for (const auto& v : vars) {
    if (ExistsEnv(v.first)) {
      _old_values[v.first] = EnvVarValue(EnvVarAction::SET, GetEnv(v.first));
    } else {
      _old_values[v.first] = EnvVarValue(EnvVarAction::UNSET, "");
    }
  }

  SetEnvVars(vars);
}

WithEnvVars::~WithEnvVars() { SetEnvVars(_old_values); }

}  // namespace blaze
