/*
 * Copyright (C) 2016 The Android Open Source Project
 *
 * 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 <procinfo/process.h>

#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#include <string>

#include <android-base/unique_fd.h>

using android::base::unique_fd;

namespace android {
namespace procinfo {

bool GetProcessInfo(pid_t tid, ProcessInfo* process_info) {
  char path[PATH_MAX];
  snprintf(path, sizeof(path), "/proc/%d", tid);

  unique_fd dirfd(open(path, O_DIRECTORY | O_RDONLY));
  if (dirfd == -1) {
    PLOG(ERROR) << "failed to open " << path;
    return false;
  }

  return GetProcessInfoFromProcPidFd(dirfd.get(), process_info);
}

static ProcessState parse_state(const char* state) {
  switch (*state) {
    case 'R':
      return kProcessStateRunning;
    case 'S':
      return kProcessStateSleeping;
    case 'D':
      return kProcessStateUninterruptibleWait;
    case 'T':
      return kProcessStateStopped;
    case 'Z':
      return kProcessStateZombie;
    default:
      LOG(ERROR) << "unknown process state: " << *state;
      return kProcessStateUnknown;
  }
}

bool GetProcessInfoFromProcPidFd(int fd, ProcessInfo* process_info) {
  int status_fd = openat(fd, "status", O_RDONLY | O_CLOEXEC);

  if (status_fd == -1) {
    PLOG(ERROR) << "failed to open status fd in GetProcessInfoFromProcPidFd";
    return false;
  }

  std::unique_ptr<FILE, decltype(&fclose)> fp(fdopen(status_fd, "r"), fclose);
  if (!fp) {
    PLOG(ERROR) << "failed to open status file in GetProcessInfoFromProcPidFd";
    close(status_fd);
    return false;
  }

  int field_bitmap = 0;
  static constexpr int finished_bitmap = 255;
  char* line = nullptr;
  size_t len = 0;

  while (getline(&line, &len, fp.get()) != -1 && field_bitmap != finished_bitmap) {
    char* tab = strchr(line, '\t');
    if (tab == nullptr) {
      continue;
    }

    size_t header_len = tab - line;
    std::string header = std::string(line, header_len);
    if (header == "Name:") {
      std::string name = line + header_len + 1;

      // line includes the trailing newline.
      name.pop_back();
      process_info->name = std::move(name);

      field_bitmap |= 1;
    } else if (header == "Pid:") {
      process_info->tid = atoi(tab + 1);
      field_bitmap |= 2;
    } else if (header == "Tgid:") {
      process_info->pid = atoi(tab + 1);
      field_bitmap |= 4;
    } else if (header == "PPid:") {
      process_info->ppid = atoi(tab + 1);
      field_bitmap |= 8;
    } else if (header == "TracerPid:") {
      process_info->tracer = atoi(tab + 1);
      field_bitmap |= 16;
    } else if (header == "Uid:") {
      process_info->uid = atoi(tab + 1);
      field_bitmap |= 32;
    } else if (header == "Gid:") {
      process_info->gid = atoi(tab + 1);
      field_bitmap |= 64;
    } else if (header == "State:") {
      process_info->state = parse_state(tab + 1);
      field_bitmap |= 128;
    }
  }

  free(line);
  return field_bitmap == finished_bitmap;
}

} /* namespace procinfo */
} /* namespace android */
