/*
 * Copyright 2013 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 "memtrack.h"

#include <ctype.h>
#include <dirent.h>
#include <fcntl.h>
#include <limits.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

#include <cutils/log.h>

#include <algorithm>
#include <vector>

#ifdef LOG_TAG
#undef LOG_TAG
#endif
#define LOG_TAG "MemTracker"

FileData::FileData(char *filename, char *buffer, size_t buffer_len)
    : data_(buffer), max_(buffer_len), cur_idx_(0), len_(0),
      read_complete_(false) {
  fd_ = open(filename, O_RDONLY);
  if (fd_ < 0) {
    read_complete_ = true;
  }
}

FileData::~FileData() {
  if (fd_ >= 0) {
    close(fd_);
  }
}

bool FileData::isAvail(size_t bytes_needed) {
  if (cur_idx_ + bytes_needed < len_) {
    return true;
  }

  if (read_complete_) {
    return false;
  }

  if (cur_idx_ != len_) {
    // Copy the leftover to the front of the buffer.
    len_ = len_ - cur_idx_;
    memcpy(data_, data_ + cur_idx_, len_);
  }

  ssize_t bytes;
  cur_idx_ = 0;
  while (cur_idx_ + bytes_needed >= len_) {
    bytes = read(fd_, data_ + len_, max_ - len_);
    if (bytes == 0 || bytes == -1) {
      read_complete_;
      break;
    }
    len_ += bytes;
  }

  return cur_idx_ + bytes_needed < len_;
}

bool FileData::getPss(size_t *pss) {
  size_t value;
  while (true) {
    if (!isAvail(4)) {
      return false;
    }

    if (data_[cur_idx_] != 'P' || data_[cur_idx_+1] != 's' ||
        data_[cur_idx_+2] != 's' || data_[cur_idx_+3] != ':') {
      // Consume the rest of the line.
      while (isAvail(1) && data_[cur_idx_++] != '\n');
    } else {
      cur_idx_ += 4;
      while (isAvail(1) && isspace(data_[cur_idx_])) {
        cur_idx_++;
      }

      value = 0;
      while (isAvail(1) && isdigit(data_[cur_idx_])) {
        value = value * 10 + data_[cur_idx_] - '0';
        cur_idx_++;
      }
      *pss = value;

      // Consume the rest of the line.
      while (isAvail(1) && data_[cur_idx_++] != '\n');

      return true;
    }
  }
}

const char *ProcessInfo::kProc = "/proc/";
const char *ProcessInfo::kCmdline = "/cmdline";
const char *ProcessInfo::kSmaps = "/smaps";

ProcessInfo::ProcessInfo() {
  memcpy(proc_file_, kProc, kProcLen);
}

ProcessInfo::~ProcessInfo() {
}

bool ProcessInfo::getInformation(int pid, char *pid_str, size_t pid_str_len) {
  memcpy(proc_file_ + kProcLen, pid_str, pid_str_len);
  memcpy(proc_file_ + kProcLen + pid_str_len, kCmdline, kCmdlineLen);

  // Read the cmdline for the process.
  int fd = open(proc_file_, O_RDONLY);
  if (fd < 0) {
    return false;
  }

  ssize_t bytes = read(fd, cmd_name_, sizeof(cmd_name_));
  close(fd);
  if (bytes == -1 || bytes == 0) {
    return false;
  }

  memcpy(proc_file_ + kProcLen + pid_str_len, kSmaps, kSmapsLen);
  FileData smaps(proc_file_, buffer_, sizeof(buffer_));

  cur_process_info_t process_info;
  size_t pss_kb;
  process_info.pss_kb = 0;
  while (smaps.getPss(&pss_kb)) {
    process_info.pss_kb += pss_kb;
  }

  if (cur_.count(cmd_name_) == 0) {
    cur_[cmd_name_] = process_info;
  } else {
    cur_[cmd_name_].pss_kb += process_info.pss_kb;
  }
  cur_[cmd_name_].pids.push_back(pid);

  return true;
}

void ProcessInfo::scan() {
  DIR *proc_dir = opendir(kProc);
  if (proc_dir == NULL) {
    perror("Cannot open directory.\n");
    exit(1);
  }

  // Clear any current pids.
  for (processes_t::iterator it = all_.begin(); it != all_.end(); ++it) {
    it->second.pids.clear();
  }

  struct dirent *dir_data;
  int len;
  bool is_pid;
  size_t pid;
  cur_.clear();
  while ((dir_data = readdir(proc_dir))) {
    // Check if the directory entry represents a pid.
    len = strlen(dir_data->d_name);
    is_pid = true;
    pid = 0;
    for (int i = 0; i < len; i++) {
      if (!isdigit(dir_data->d_name[i])) {
        is_pid = false;
        break;
      }
      pid = pid * 10 + dir_data->d_name[i] - '0';
    }
    if (is_pid) {
      getInformation(pid, dir_data->d_name, len);
    }
  }
  closedir(proc_dir);

  // Loop through the current processes and add them into our real list.
  for (cur_processes_t::const_iterator it = cur_.begin();
       it != cur_.end(); ++it) {

    if (all_.count(it->first) == 0) {
      // Initialize all of the variables.
      all_[it->first].num_samples = 0;
      all_[it->first].name = it->first;
      all_[it->first].avg_pss_kb = 0;
      all_[it->first].min_pss_kb = 0;
      all_[it->first].max_pss_kb = 0;
    }

    if (it->second.pids.size() > all_[it->first].max_num_pids) {
      all_[it->first].max_num_pids = it->second.pids.size();
    }

    all_[it->first].pids = it->second.pids;

    if (it->second.pss_kb > all_[it->first].max_pss_kb) {
      all_[it->first].max_pss_kb = it->second.pss_kb;
    }

    if (all_[it->first].min_pss_kb == 0 ||
        it->second.pss_kb < all_[it->first].min_pss_kb) {
      all_[it->first].min_pss_kb = it->second.pss_kb;
    }

    all_[it->first].last_pss_kb = it->second.pss_kb;

    computeAvg(&all_[it->first].avg_pss_kb, it->second.pss_kb,
               all_[it->first].num_samples);
    all_[it->first].num_samples++;
  }
}

bool comparePss(const process_info_t *first, const process_info_t *second) {
  return first->max_pss_kb > second->max_pss_kb;
}

void ProcessInfo::dumpToLog() {
  list_.clear();
  for (processes_t::const_iterator it = all_.begin(); it != all_.end(); ++it) {
    list_.push_back(&it->second);
  }

  // Now sort the list.
  std::sort(list_.begin(), list_.end(), comparePss);

  ALOGI("Dumping process list");
  for (std::vector<const process_info_t *>::const_iterator it = list_.begin();
       it != list_.end(); ++it) {
    ALOGI("  Name: %s", (*it)->name.c_str());
    ALOGI("    Max running processes: %d", (*it)->max_num_pids);
    if ((*it)->pids.size() > 0) {
      ALOGI("    Currently running pids:");
      for (std::vector<int>::const_iterator pid_it = (*it)->pids.begin();
           pid_it != (*it)->pids.end(); ++pid_it) {
        ALOGI("      %d", *pid_it);
      }
    }

    ALOGI("    Min  PSS %0.4fM", (*it)->min_pss_kb/1024.0);
    ALOGI("    Avg  PSS %0.4fM", (*it)->avg_pss_kb/1024.0);
    ALOGI("    Max  PSS %0.4fM", (*it)->max_pss_kb/1024.0);
    ALOGI("    Last PSS %0.4fM", (*it)->last_pss_kb/1024.0);
  }
}

void usage() {
  printf("Usage: memtrack [--verbose | --quiet] [--scan_delay TIME_SECS]\n");
  printf("  --scan_delay TIME_SECS\n");
  printf("    The amount of delay in seconds between scans.\n");
  printf("  --verbose\n");
  printf("    Print information about the scans to stdout only.\n");
  printf("  --quiet\n");
  printf("    Nothing will be printed to stdout.\n");
  printf("  All scan data is dumped to the android log using the tag %s\n",
         LOG_TAG);
}

int SignalReceived = 0;

int SignalsToHandle[] = {
  SIGTSTP,
  SIGINT,
  SIGHUP,
  SIGPIPE,
  SIGUSR1,
};

void handleSignal(int signo) {
  if (SignalReceived == 0) {
    SignalReceived = signo;
  }
}

int main(int argc, char **argv) {
  if (geteuid() != 0) {
    printf("Must be run as root.\n");
    exit(1);
  }

  bool verbose = false;
  bool quiet = false;
  unsigned int scan_delay_sec = DEFAULT_SLEEP_DELAY_SECONDS;
  for (int i = 1; i < argc; i++) {
    if (strcmp(argv[i], "--verbose") == 0) {
      verbose = true;
    } else if (strcmp(argv[i], "--quiet") == 0) {
      quiet = true;
    } else if (strcmp(argv[i], "--scan_delay") == 0) {
      if (i+1 == argc) {
        printf("The %s options requires a single argument.\n", argv[i]);
        usage();
        exit(1);
      }
      scan_delay_sec = atoi(argv[++i]);
    } else {
      printf("Unknown option %s\n", argv[i]);
      usage();
      exit(1);
    }
  }
  if (quiet && verbose) {
    printf("Both --quiet and --verbose cannot be specified.\n");
    usage();
    exit(1);
  }

  // Set up the signal handlers.
  for (size_t i = 0; i < sizeof(SignalsToHandle)/sizeof(int); i++) {
    if (signal(SignalsToHandle[i], handleSignal) == SIG_ERR) {
      printf("Unable to handle signal %d\n", SignalsToHandle[i]);
      exit(1);
    }
  }

  ProcessInfo proc_info;

  if (!quiet) {
    printf("Hit Ctrl-Z or send SIGUSR1 to pid %d to print the current list of\n",
           getpid());
    printf("processes.\n");
    printf("Hit Ctrl-C to print the list of processes and terminate.\n");
  }

  struct timespec t;
  unsigned long long nsecs;
  while (true) {
    if (verbose) {
      memset(&t, 0, sizeof(t));
      clock_gettime(CLOCK_MONOTONIC, &t);
      nsecs = (unsigned long long)t.tv_sec*NS_PER_SEC + t.tv_nsec;
    }
    proc_info.scan();
    if (verbose) {
      memset(&t, 0, sizeof(t));
      clock_gettime(CLOCK_MONOTONIC, &t);
      nsecs = ((unsigned long long)t.tv_sec*NS_PER_SEC + t.tv_nsec) - nsecs;
      printf("Scan Time %0.4f\n", ((double)nsecs)/NS_PER_SEC);
    }

    if (SignalReceived != 0) {
      proc_info.dumpToLog();
      if (SignalReceived != SIGUSR1 && SignalReceived != SIGTSTP) {
        if (!quiet) {
          printf("Terminating...\n");
        }
        exit(1);
      }
      SignalReceived = 0;
    }
    sleep(scan_delay_sec);
  }
}
