// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/process/internal_aix.h"

#include <sys/procfs.h>

#include <errno.h>
#include <fcntl.h>
#include <limits.h>
#include <unistd.h>

#include <map>
#include <string>
#include <vector>

#include "base/files/file_util.h"
#include "base/logging.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_split.h"
#include "base/strings/string_util.h"
#include "base/threading/thread_restrictions.h"
#include "base/time/time.h"
#include "starboard/types.h"

// Not defined on AIX by default.
#define NAME_MAX 255

namespace base {
namespace internalAIX {

const char kProcDir[] = "/proc";

const char kStatFile[] = "psinfo";  // AIX specific

FilePath GetProcPidDir(pid_t pid) {
  return FilePath(kProcDir).Append(IntToString(pid));
}

pid_t ProcDirSlotToPid(const char* d_name) {
  int i;
  for (i = 0; i < NAME_MAX && d_name[i]; ++i) {
    if (!IsAsciiDigit(d_name[i])) {
      return 0;
    }
  }
  if (i == NAME_MAX)
    return 0;

  // Read the process's command line.
  pid_t pid;
  std::string pid_string(d_name);
  if (!StringToInt(pid_string, &pid)) {
    NOTREACHED();
    return 0;
  }
  return pid;
}

bool ReadProcFile(const FilePath& file, struct psinfo* info) {
  // Synchronously reading files in /proc is safe.
  ThreadRestrictions::ScopedAllowIO allow_io;
  int fileId;
  if ((fileId = open(file.value().c_str(), O_RDONLY)) < 0) {
    DLOG(WARNING) << "Failed to open " << file.MaybeAsASCII()
                  << " errno = " << errno;
    return false;
  }

  if (read(fileId, info, sizeof(*info)) < 0) {
    DLOG(WARNING) << "Failed to read " << file.MaybeAsASCII()
                  << " errno = " << errno;
    return false;
  }

  return true;
}

bool ReadProcStats(pid_t pid, struct psinfo* info) {
  FilePath stat_file = internalAIX::GetProcPidDir(pid).Append(kStatFile);
  return ReadProcFile(stat_file, info);
}

bool ParseProcStats(struct psinfo& stats_data,
                    std::vector<std::string>* proc_stats) {
  // The stat file is formatted as:
  // struct psinfo
  // see -
  // https://www.ibm.com/support/knowledgecenter/ssw_aix_71/com.ibm.aix.files/proc.htm
  proc_stats->clear();
  // PID.
  proc_stats->push_back(IntToString(stats_data.pr_pid));
  // Process name without parentheses. // 1
  proc_stats->push_back(stats_data.pr_fname);
  // Process State (Not available)  // 2
  proc_stats->push_back("0");
  // Process id of parent  // 3
  proc_stats->push_back(IntToString(stats_data.pr_ppid));

  // Process group id // 4
  proc_stats->push_back(IntToString(stats_data.pr_pgid));

  return true;
}

typedef std::map<std::string, std::string> ProcStatMap;
void ParseProcStat(const std::string& contents, ProcStatMap* output) {
  StringPairs key_value_pairs;
  SplitStringIntoKeyValuePairs(contents, ' ', '\n', &key_value_pairs);
  for (size_t i = 0; i < key_value_pairs.size(); ++i) {
    output->insert(key_value_pairs[i]);
  }
}

int64_t GetProcStatsFieldAsInt64(const std::vector<std::string>& proc_stats,
                                 ProcStatsFields field_num) {
  DCHECK_GE(field_num, VM_PPID);
  CHECK_LT(static_cast<size_t>(field_num), proc_stats.size());

  int64_t value;
  return StringToInt64(proc_stats[field_num], &value) ? value : 0;
}

size_t GetProcStatsFieldAsSizeT(const std::vector<std::string>& proc_stats,
                                ProcStatsFields field_num) {
  DCHECK_GE(field_num, VM_PPID);
  CHECK_LT(static_cast<size_t>(field_num), proc_stats.size());

  size_t value;
  return StringToSizeT(proc_stats[field_num], &value) ? value : 0;
}

int64_t ReadProcStatsAndGetFieldAsInt64(pid_t pid, ProcStatsFields field_num) {
  struct psinfo stats_data;
  if (!ReadProcStats(pid, &stats_data))
    return 0;
  std::vector<std::string> proc_stats;
  if (!ParseProcStats(stats_data, &proc_stats))
    return 0;

  return GetProcStatsFieldAsInt64(proc_stats, field_num);
}

size_t ReadProcStatsAndGetFieldAsSizeT(pid_t pid, ProcStatsFields field_num) {
  struct psinfo stats_data;
  if (!ReadProcStats(pid, &stats_data))
    return 0;
  std::vector<std::string> proc_stats;
  if (!ParseProcStats(stats_data, &proc_stats))
    return 0;
  return GetProcStatsFieldAsSizeT(proc_stats, field_num);
}

}  // namespace internalAIX
}  // namespace base
