// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The ASF licenses this file
// to you 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 <stdio.h>
#if defined(__linux__)
#include <syscall.h>
#else
#include <sys/syscall.h>
#endif
#include <unistd.h>
#include <array>
#include <fstream> // IWYU pragma: keep
#include <iostream>
#include <memory>
#include <string>

#include "utils/preloadable.h"
#include "utils/process_utils.h"
#include "utils/time_utils.h"

using std::ios_base;
using std::ifstream;
using std::string;

namespace dsn {
namespace utils {

__thread tls_tid s_tid;
int get_current_tid_internal() { return static_cast<int>(syscall(SYS_gettid)); }

int pipe_execute(const char *command, std::ostream &output)
{
    std::array<char, 256> buffer;
    int retcode = 0;

    {
        std::shared_ptr<FILE> command_pipe(popen(command, "r"),
                                           [&retcode](FILE *p) { retcode = pclose(p); });
        while (!feof(command_pipe.get())) {
            if (fgets(buffer.data(), 256, command_pipe.get()) != NULL)
                output << buffer.data();
        }
    }
    return retcode;
}

void process_mem_usage(double &vm_usage, double &resident_set)
{
    vm_usage = 0.0;
    resident_set = 0.0;

    // 'file' stat seems to give the most reliable results
    //
    ifstream stat_stream("/proc/self/stat", ios_base::in);

    // dummy vars for leading entries in stat that we don't care about
    //
    string pid, comm, state, ppid, pgrp, session, tty_nr;
    string tpgid, flags, minflt, cminflt, majflt, cmajflt;
    string utime, stime, cutime, cstime, priority, nice;
    string O, itrealvalue, starttime;

    // the two fields we want
    //
    unsigned long vsize;
    long rss;

    stat_stream >> pid >> comm >> state >> ppid >> pgrp >> session >> tty_nr >> tpgid >> flags >>
        minflt >> cminflt >> majflt >> cmajflt >> utime >> stime >> cutime >> cstime >> priority >>
        nice >> O >> itrealvalue >> starttime >> vsize >> rss; // don't care about the rest

    stat_stream.close();

    static long page_size_kb =
        sysconf(_SC_PAGE_SIZE) / 1024; // in case x86-64 is configured to use 2MB pages
    vm_usage = vsize / 1024.0;
    resident_set = rss * page_size_kb;
}

class record_process_start_time : public preloadable<record_process_start_time>
{
public:
    record_process_start_time()
    {
        mills = get_current_physical_time_ns() / 1000000;
        time_ms_to_string(mills, date_time_mills);
    }
    uint64_t mills = 0;
    char date_time_mills[64] = {0};
};

//
// if you call these functions before "main" function,
// the memory space for these variables have been allocated,
// but the values aren't initialized as the constructor
// of "static_module" may not been called yet.
//
uint64_t process_start_millis() { return record_process_start_time::s_instance.mills; }
const char *process_start_date_time_mills()
{
    return record_process_start_time::s_instance.date_time_mills;
}
}
}
