/*
 * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved.
 * Copyright (c) 2023, 2024, Red Hat, Inc. and/or its affiliates.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 *
 */

#include "nmt/memMapPrinter.hpp"
#include "procMapsParser.hpp"
#include "runtime/os.hpp"
#include "utilities/align.hpp"
#include "utilities/globalDefinitions.hpp"
#include "utilities/ostream.hpp"
#include "utilities/powerOfTwo.hpp"

#include <limits.h>

class ProcSmapsSummary {
  unsigned _num_mappings;
  size_t _vsize;        // combined virtual size
  size_t _rss;          // combined resident set size
  size_t _committed;    // combined committed size
  size_t _shared;       // combined shared size
  size_t _swapped_out;  // combined amount of swapped-out memory
  size_t _hugetlb;      // combined amount of memory backed by explicit huge pages
  size_t _thp;          // combined amount of memory backed by THPs
public:
  ProcSmapsSummary() : _num_mappings(0), _vsize(0), _rss(0), _committed(0), _shared(0),
                     _swapped_out(0), _hugetlb(0), _thp(0) {}
  void add_mapping(const ProcSmapsInfo& info) {
    _num_mappings++;
    _vsize += info.vsize();
    _rss += info.rss;
    _committed += info.nr ? 0 : info.vsize();
    _shared += info.sh ? info.vsize() : 0;
    _swapped_out += info.swap;
    _hugetlb += info.private_hugetlb + info.shared_hugetlb;
    _thp += info.anonhugepages;
  }

  void print_on(const MappingPrintSession& session) const {
    outputStream* st = session.out();
    st->print_cr("Number of mappings: %u", _num_mappings);
    st->print_cr("             vsize: %zu (" PROPERFMT ")", _vsize, PROPERFMTARGS(_vsize));
    st->print_cr("               rss: %zu (" PROPERFMT ")", _rss, PROPERFMTARGS(_rss));
    st->print_cr("         committed: %zu (" PROPERFMT ")", _committed, PROPERFMTARGS(_committed));
    st->print_cr("            shared: %zu (" PROPERFMT ")", _shared, PROPERFMTARGS(_shared));
    st->print_cr("       swapped out: %zu (" PROPERFMT ")", _swapped_out, PROPERFMTARGS(_swapped_out));
    st->print_cr("         using thp: %zu (" PROPERFMT ")", _thp, PROPERFMTARGS(_thp));
    st->print_cr("           hugetlb: %zu (" PROPERFMT ")", _hugetlb, PROPERFMTARGS(_hugetlb));
  }
};

class ProcSmapsPrinter {
  const MappingPrintSession& _session;
public:
  ProcSmapsPrinter(const MappingPrintSession& session) :
    _session(session)
  {}

  void print_single_mapping(const ProcSmapsInfo& info) const {
    outputStream* st = _session.out();
#define INDENT_BY(n)          \
  if (st->fill_to(n) == 0) {  \
    st->print(" ");           \
  }
    st->print(PTR_FORMAT "-" PTR_FORMAT, p2i(info.from), p2i(info.to));
    INDENT_BY(38);
    st->print("%12zu", info.vsize());
    INDENT_BY(51);
    st->print("%s", info.prot);
    INDENT_BY(56);
    st->print("%12zu", info.rss);
    INDENT_BY(69);
    st->print("%12zu", info.private_hugetlb);
    INDENT_BY(82);
    st->print(EXACTFMT, EXACTFMTARGS(info.kernelpagesize));
    {
      INDENT_BY(87);
      int num_printed = 0;
#define PRINTIF(cond, s)                                    \
      if (cond) {                                           \
        st->print("%s%s", (num_printed > 0 ? "," : ""), s); \
        num_printed++;                                      \
      }
      PRINTIF(info.sh, "shrd");
      PRINTIF(!info.nr, "com");
      PRINTIF(info.swap > 0, "swap");
      PRINTIF(info.ht, "huge");
      PRINTIF(info.anonhugepages > 0, "thp");
      PRINTIF(info.hg, "thpad");
      PRINTIF(info.nh, "nothp");
      if (num_printed == 0) {
        st->print("-");
      }
#undef PRINTIF
    }
    INDENT_BY(104);
    if (!_session.print_nmt_info_for_region(info.from, info.to)) {
      st->print("-");
    }
    INDENT_BY(142);
    st->print_raw(info.filename[0] == '\0' ? "-" : info.filename);
  #undef INDENT_BY
    st->cr();
  }

  void print_legend() const {
    outputStream* st = _session.out();
    st->print_cr("from, to, vsize: address range and size");
    st->print_cr("prot:            protection");
    st->print_cr("rss:             resident set size");
    st->print_cr("hugetlb:         size of private hugetlb pages");
    st->print_cr("pgsz:            page size");
    st->print_cr("notes:           mapping information  (detail mode only)");
    st->print_cr("                      shrd: mapping is shared");
    st->print_cr("                       com: mapping committed (swap space reserved)");
    st->print_cr("                      swap: mapping partly or completely swapped out");
    st->print_cr("                       thp: mapping uses THP");
    st->print_cr("                     thpad: mapping is THP-madvised");
    st->print_cr("                     nothp: mapping is forbidden to use THP");
    st->print_cr("                      huge: mapping uses hugetlb pages");
    st->print_cr("vm info:         VM information (requires NMT)");
    {
      StreamIndentor si(st, 16);
      _session.print_nmt_flag_legend();
    }
    st->print_cr("file:            file mapped, if mapping is not anonymous");
  }

  void print_header() const {
    outputStream* st = _session.out();
    //            0         1         2         3         4         5         6         7         8         9         0         1         2         3         4         5         6         7
    //            012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
    //            0x0000000414000000-0x0000000453000000 123456789012 rw-p 123456789012 123456789012 16g  thp,thpadv       STACK-340754-Monitor-Deflation-Thread /shared/tmp.txt
    st->print_cr("from               to                        vsize prot          rss      hugetlb pgsz notes            info                                  file");
    st->print_cr("========================================================================================================================================================================");
  }
};

void MemMapPrinter::pd_print_all_mappings(const MappingPrintSession& session) {
  constexpr char filename[] = "/proc/self/smaps";
  FILE* f = os::fopen(filename, "r");
  if (f == nullptr) {
    session.out()->print_cr("Cannot open %s", filename);
    return;
  }

  ProcSmapsPrinter printer(session);
  ProcSmapsSummary summary;

  outputStream* const st = session.out();

  printer.print_legend();
  st->cr();
  printer.print_header();

  ProcSmapsInfo info;
  ProcSmapsParser parser(f);
  while (parser.parse_next(info)) {
    printer.print_single_mapping(info);
    summary.add_mapping(info);
  }
  st->cr();

  summary.print_on(session);
  st->cr();

  ::fclose(f);
}
