/*
 * Copyright (C) 2008 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.
 */

#ifndef FRAMEWORK_NATIVE_CMD_DUMPSTATE_H_
#define FRAMEWORK_NATIVE_CMD_DUMPSTATE_H_

#include <time.h>
#include <unistd.h>
#include <stdbool.h>
#include <stdio.h>

#include <string>
#include <vector>

#include <aidl/android/hardware/dumpstate/IDumpstateDevice.h>
#include <android-base/macros.h>
#include <android-base/unique_fd.h>
#include <android/hardware/dumpstate/1.1/types.h>
#include <android/os/BnIncidentAuthListener.h>
#include <android/os/IDumpstate.h>
#include <android/os/IDumpstateListener.h>
#include <utils/StrongPointer.h>
#include <ziparchive/zip_writer.h>

#include "DumpstateUtil.h"
#include "DumpPool.h"
#include "TaskQueue.h"

// TODO: move everything under this namespace
// TODO: and then remove explicitly android::os::dumpstate:: prefixes
namespace android {
namespace os {

struct DumpstateOptions;

namespace dumpstate {

class DumpstateTest;
class ProgressTest;
class ZippedBugReportStreamTest;

}  // namespace dumpstate
}  // namespace os
}  // namespace android

class ZipWriter;

// TODO: remove once moved to HAL
#ifdef __cplusplus
extern "C" {
#endif

/*
 * Helper class used to report how long it takes for a section to finish.
 *
 * Typical usage:
 *
 *    DurationReporter duration_reporter(title);
 *
 */
class DurationReporter {
  public:
    explicit DurationReporter(const std::string& title, bool logcat_only = false,
                              bool verbose = false, int duration_fd = STDOUT_FILENO);

    ~DurationReporter();

  private:
    std::string title_;
    bool logcat_only_;
    bool verbose_;
    uint64_t started_;
    int duration_fd_;

    DISALLOW_COPY_AND_ASSIGN(DurationReporter);
};

/*
 * Keeps track of current progress and estimated max, saving stats on file to tune up future runs.
 *
 * Each `dumpstate` section contributes to the total weight by an individual weight, so the overall
 * progress can be calculated by dividing the estimate max progress by the current progress.
 *
 * The estimated max progress is initially set to a value (`kDefaultMax) defined empirically, but
 * it's adjusted after each dumpstate run by storing the average duration in a file.
 *
 */
class Progress {
    friend class android::os::dumpstate::ProgressTest;
    friend class android::os::dumpstate::DumpstateTest;

  public:
    /*
     * Default estimation of the max duration of a bugreport generation.
     *
     * It does not need to match the exact sum of all sections, but ideally it should to be slight
     * more than such sum: a value too high will cause the bugreport to finish before the user
     * expected (for example, jumping from 70% to 100%), while a value too low will cause the
     * progress to get stuck at an almost-finished value (like 99%) for a while.
     *
     * This constant is only used when the average duration from previous runs cannot be used.
     */
    static const int kDefaultMax;

    explicit Progress(const std::string& path = "");

    // Gets the current progress.
    int32_t Get() const;

    // Gets the current estimated max progress.
    int32_t GetMax() const;

    // Gets the initial estimated max progress.
    int32_t GetInitialMax() const;

    // Increments progress (ignored if not positive).
    // Returns `true` if the max progress increased as well.
    bool Inc(int32_t delta);

    // Persist the stats.
    void Save();

    void Dump(int fd, const std::string& prefix) const;

  private:
    Progress(int32_t initial_max, float growth_factor,
             const std::string& path = "");                                // Used by test cases.
    Progress(int32_t initial_max, int32_t progress, float growth_factor);  // Used by test cases.
    void Load();
    int32_t initial_max_;
    int32_t progress_;
    int32_t max_;
    float growth_factor_;
    int32_t n_runs_;
    int32_t average_max_;
    std::string path_;
};

/*
 * List of supported zip format versions.
 *
 * See bugreport-format.md for more info.
 */
static std::string VERSION_CURRENT = "2.0";

/*
 * "Alias" for the current version.
 */
static std::string VERSION_DEFAULT = "default";

/*
 * Directory used by Dumpstate binary to keep its local files.
 */
static const std::string DUMPSTATE_DIRECTORY = "/bugreports";

/*
 * Structure that contains the information of an open dump file.
 */
struct DumpData {
    // Path of the file.
    std::string name;

    // Open file descriptor for the file.
    android::base::unique_fd fd;

    // Modification time of the file.
    time_t mtime;
};

/*
 * Main class driving a bugreport generation.
 *
 * Currently, it only contains variables that are accessed externally, but gradually the functions
 * that are spread accross utils.cpp and dumpstate.cpp will be moved to it.
 */
class Dumpstate {
    friend class android::os::dumpstate::DumpstateTest;
    friend class android::os::dumpstate::ZippedBugReportStreamTest;

  public:
    enum RunStatus { OK, HELP, INVALID_INPUT, ERROR, USER_CONSENT_DENIED, USER_CONSENT_TIMED_OUT };

    // The mode under which the bugreport should be run. Each mode encapsulates a few options.
    enum BugreportMode {
        BUGREPORT_FULL = android::os::IDumpstate::BUGREPORT_MODE_FULL,
        BUGREPORT_INTERACTIVE = android::os::IDumpstate::BUGREPORT_MODE_INTERACTIVE,
        BUGREPORT_REMOTE = android::os::IDumpstate::BUGREPORT_MODE_REMOTE,
        BUGREPORT_WEAR = android::os::IDumpstate::BUGREPORT_MODE_WEAR,
        BUGREPORT_TELEPHONY = android::os::IDumpstate::BUGREPORT_MODE_TELEPHONY,
        BUGREPORT_WIFI = android::os::IDumpstate::BUGREPORT_MODE_WIFI,
        BUGREPORT_ONBOARDING = android::os::IDumpstate::BUGREPORT_MODE_ONBOARDING,
        BUGREPORT_DEFAULT = android::os::IDumpstate::BUGREPORT_MODE_DEFAULT
    };

    // The flags used to customize bugreport requests.
    enum BugreportFlag {
        BUGREPORT_USE_PREDUMPED_UI_DATA =
          android::os::IDumpstate::BUGREPORT_FLAG_USE_PREDUMPED_UI_DATA,
        BUGREPORT_FLAG_DEFER_CONSENT =
          android::os::IDumpstate::BUGREPORT_FLAG_DEFER_CONSENT,
          BUGREPORT_FLAG_KEEP_BUGREPORT_ON_RETRIEVAL =
                    android::os::IDumpstate::BUGREPORT_FLAG_KEEP_BUGREPORT_ON_RETRIEVAL
    };

    static android::os::dumpstate::CommandOptions DEFAULT_DUMPSYS;

    static Dumpstate& GetInstance();

    /* Initialize dumpstate fields before starting bugreport generation */
    void Initialize();

    /*
     * Forks a command, waits for it to finish, and returns its status.
     *
     * |title| description of the command printed on `stdout` (or empty to skip
     * description).
     * |full_command| array containing the command (first entry) and its arguments.
     * Must contain at least one element.
     * |options| optional argument defining the command's behavior.
     * |out_fd| A fd to support the DumpPool to output results to a temporary
     * file. Using STDOUT_FILENO if it's not running in the parallel task.
     */
    int RunCommand(const std::string& title, const std::vector<std::string>& fullCommand,
                   const android::os::dumpstate::CommandOptions& options =
                       android::os::dumpstate::CommandOptions::DEFAULT,
                   bool verbose_duration = false, int out_fd = STDOUT_FILENO);

    /*
     * Runs `dumpsys` with the given arguments, automatically setting its timeout
     * (`-T` argument)
     * according to the command options.
     *
     * |title| description of the command printed on `stdout` (or empty to skip
     * description).
     * |dumpsys_args| `dumpsys` arguments (except `-t`).
     * |options| optional argument defining the command's behavior.
     * |dumpsys_timeout| when > 0, defines the value passed to `dumpsys -T` (otherwise it uses the
     * timeout from `options`)
     * |out_fd| A fd to support the DumpPool to output results to a temporary
     * file. Using STDOUT_FILENO if it's not running in the parallel task.
     */
    void RunDumpsys(const std::string& title, const std::vector<std::string>& dumpsys_args,
                    const android::os::dumpstate::CommandOptions& options = DEFAULT_DUMPSYS,
                    long dumpsys_timeout_ms = 0, int out_fd = STDOUT_FILENO);

    /*
     * Prints the contents of a file.
     *
     * |title| description of the command printed on `stdout` (or empty to skip
     * description).
     * |path| location of the file to be dumped.
     */
    int DumpFile(const std::string& title, const std::string& path);

    /*
     * Adds a new entry to the existing zip file.
     * */
    bool AddZipEntry(const std::string& entry_name, const std::string& entry_path);

    /*
     * Adds a new entry to the existing zip file.
     *
     * |entry_name| destination path of the new entry.
     * |fd| file descriptor to read from.
     * |timeout| timeout to terminate the read if not completed. Set
     * value of 0s (default) to disable timeout.
     */
    android::status_t AddZipEntryFromFd(const std::string& entry_name, int fd,
                                        std::chrono::milliseconds timeout);

    /*
     * Adds a text entry to the existing zip file.
     */
    bool AddTextZipEntry(const std::string& entry_name, const std::string& content);

    /*
     * Adds all files from a directory to the zipped bugreport file.
     */
    void AddDir(const std::string& dir, bool recursive);

    /*
     * Takes a screenshot and save it to the given `path`.
     *
     * If `path` is empty, uses a standard path based on the bugreport name.
     */
    void TakeScreenshot(const std::string& path = "");

    /////////////////////////////////////////////////////////////////////
    // TODO: members below should be private once refactor is finished //
    /////////////////////////////////////////////////////////////////////

    // TODO: temporary method until Dumpstate object is properly set
    void SetProgress(std::unique_ptr<Progress> progress);

    // Dumps Dalvik and native stack traces, sets the trace file location to path
    // if it succeeded.
    // Note that it returns early if user consent is denied with status USER_CONSENT_DENIED.
    // Returns OK in all other cases.
    RunStatus DumpTraces(const char** path);

    /*
     * |out_fd| A fd to support the DumpPool to output results to a temporary file.
     * Dumpstate can pick up later and output to the bugreport. Using STDOUT_FILENO
     * if it's not running in the parallel task.
     */
    void DumpstateBoard(int out_fd = STDOUT_FILENO);

    /*
     * Updates the overall progress of the bugreport generation by the given weight increment.
     */
    void UpdateProgress(int32_t delta);

    /* Prints the dumpstate header on `stdout`. */
    void PrintHeader() const;

    /*
     * Adds the temporary report to the existing .zip file, closes the .zip file, and removes the
     * temporary file.
     */
    bool FinishZipFile();

    /* Constructs a full path inside directory with file name formatted using the given suffix. */
    std::string GetPath(const std::string& directory, const std::string& suffix) const;

    /* Constructs a full path inside bugreport_internal_dir_ with file name formatted using the
     * given suffix. */
    std::string GetPath(const std::string& suffix) const;

    /* Returns true if the current version supports priority dump feature. */
    bool CurrentVersionSupportsPriorityDumps() const;

    struct DumpOptions;

    /**
     * Pre-dump critical UI data, e.g. data stored in short ring buffers that might get lost
     * by the time the actual bugreport is requested.
     */
    void PreDumpUiData();

    /*
     * Main entry point for running a complete bugreport.
     *
     * Initialize() dumpstate before calling this method.
     *
     */
    RunStatus Run(int32_t calling_uid, const std::string& calling_package);

    /*
     * Entry point for retrieving a previous-generated bugreport.
     *
     * Initialize() dumpstate before calling this method.
     */
    RunStatus Retrieve(int32_t calling_uid, const std::string& calling_package,
                        const bool keep_bugreport_on_retrieval);



    RunStatus ParseCommandlineAndRun(int argc, char* argv[]);

    /* Deletes in-progress files */
    void Cancel();

    /* Sets runtime options. */
    void SetOptions(std::unique_ptr<DumpOptions> options);

    /*
     * Returns true if user consent is necessary and has been denied.
     * Consent is only necessary if the caller has asked to copy over the bugreport to a file they
     * provided.
     */
    bool IsUserConsentDenied() const;

    /*
     * Returns true if dumpstate is called by bugreporting API
     */
    bool CalledByApi() const;

    /*
     * Enqueues a task to the dumpstate's TaskQueue if the parallel run is enabled,
     * otherwise invokes it immediately. The task adds file at path entry_path
     * as a zip file entry with name entry_name. Unlinks entry_path when done.
     *
     * All enqueued tasks will be executed in the dumpstate's FinishZipFile method
     * before the zip file is finished. Tasks will be cancelled in dumpstate's
     * ShutdownDumpPool method if they have never been called.
     */
    void EnqueueAddZipEntryAndCleanupIfNeeded(const std::string& entry_name,
            const std::string& entry_path);

    /*
     * Structure to hold options that determine the behavior of dumpstate.
     */
    struct DumpOptions {
        bool do_vibrate = true;
        // Writes bugreport zipped file to a socket.
        bool stream_to_socket = false;
        // Writes generation progress updates to a socket.
        bool progress_updates_to_socket = false;
        bool do_screenshot = false;
        bool is_screenshot_copied = false;
        bool is_consent_deferred = false;
        bool is_remote_mode = false;
        bool show_header_only = false;
        bool telephony_only = false;
        bool wifi_only = false;
        bool onboarding_only = false;
        // Trimmed-down version of dumpstate to only include whitelisted logs.
        bool limited_only = false;
        // Whether progress updates should be published.
        bool do_progress_updates = false;
        // this is used to derive dumpstate HAL bug report mode
        // TODO(b/148168577) get rid of the AIDL values, replace them with the HAL values instead.
        // The HAL is actually an API surface that can be validated, while the AIDL is not (@hide).
        BugreportMode bugreport_mode = Dumpstate::BugreportMode::BUGREPORT_DEFAULT;
        // Will use data collected through a previous call to PreDumpUiData().
        bool use_predumped_ui_data;
        // File descriptor to output zip file. Takes precedence over out_dir.
        android::base::unique_fd bugreport_fd;
        // File descriptor to screenshot file.
        android::base::unique_fd screenshot_fd;
        // Custom output directory.
        std::string out_dir;
        // Bugreport mode of the bugreport as a string
        std::string bugreport_mode_string;
        // Command-line arguments as string
        std::string args;
        // Notification title and description
        std::string notification_title;
        std::string notification_description;

        /* Initializes options from commandline arguments. */
        RunStatus Initialize(int argc, char* argv[]);

        /* Initializes options from the requested mode. */
        void Initialize(BugreportMode bugreport_mode, int bugreport_flags,
                        const android::base::unique_fd& bugreport_fd,
                        const android::base::unique_fd& screenshot_fd,
                        bool is_screenshot_requested);

        /* Returns true if the options set so far are consistent. */
        bool ValidateOptions() const;

        /* Returns if options specified require writing to custom file location */
        bool OutputToCustomFile() {
            // Custom location is only honored in limited mode.
            return limited_only && !out_dir.empty() && bugreport_fd.get() == -1;
        }
    };

    // TODO: initialize fields on constructor
    // dumpstate id - unique after each device reboot.
    uint32_t id_;

    // dumpstate pid
    pid_t pid_;

    // Runtime options.
    std::unique_ptr<DumpOptions> options_;

    // Last progress that was sent to the listener [0-100].
    int last_reported_percent_progress_ = 0;

    // Whether it should take an screenshot earlier in the process.
    bool do_early_screenshot_ = false;

    std::unique_ptr<Progress> progress_;

    // When set, defines a socket file-descriptor use to report progress to bugreportz
    // or to stream the zipped file to.
    int control_socket_fd_ = -1;

    // Bugreport format version;
    std::string version_ = VERSION_CURRENT;

    time_t now_;

    // Base name (without suffix or extensions) of the bugreport files, typically
    // `bugreport-BUILD_ID`.
    std::string base_name_;

    // Name is the suffix part of the bugreport files - it's typically the date,
    // but it could be changed by the user..
    std::string name_;

    std::string bugreport_internal_dir_ = DUMPSTATE_DIRECTORY;

    // Full path of the temporary file containing the bugreport, inside bugreport_internal_dir_.
    // At the very end this file is pulled into the zip file.
    std::string tmp_path_;

    // Full path of the file containing the dumpstate logs, inside bugreport_internal_dir_.
    // This is useful for debugging.
    std::string log_path_;

    // Full path of the bugreport zip file inside bugreport_internal_dir_.
    std::string path_;

    // Full path of the file containing the screenshot (when requested).
    std::string screenshot_path_;

    // Pointer to the zipped file.
    std::unique_ptr<FILE, int (*)(FILE*)> zip_file{nullptr, fclose};

    // Pointer to the zip structure.
    std::unique_ptr<ZipWriter> zip_writer_;

    // Binder object listening to progress.
    android::sp<android::os::IDumpstateListener> listener_;

    // List of open tombstone dump files.
    std::vector<DumpData> tombstone_data_;

    // List of open ANR dump files.
    std::vector<DumpData> anr_data_;

    // List of open Java traces files in the anr directory.
    std::vector<DumpData> anr_trace_data_;

    // List of open shutdown checkpoint files.
    std::vector<DumpData> shutdown_checkpoints_;

    // A thread pool to execute dump tasks simultaneously if the parallel run is enabled.
    std::unique_ptr<android::os::dumpstate::DumpPool> dump_pool_;

    // A task queue to collect adding zip entry tasks inside dump tasks if the
    // parallel run is enabled.
    std::unique_ptr<android::os::dumpstate::TaskQueue> zip_entry_tasks_;

    // A callback to IncidentCompanion service, which checks user consent for sharing the
    // bugreport with the calling app. If the user has not responded yet to the dialog it will
    // be neither confirmed nor denied.
    class ConsentCallback : public android::os::BnIncidentAuthListener {
      public:
        ConsentCallback();
        android::binder::Status onReportApproved() override;
        android::binder::Status onReportDenied() override;

        enum ConsentResult { APPROVED, DENIED, UNAVAILABLE };

        ConsentResult getResult();

        // Returns the time since creating this listener
        uint64_t getElapsedTimeMs() const;

      private:
        ConsentResult result_;
        uint64_t start_time_;
        std::mutex lock_;
    };

  private:
    RunStatus RunInternal(int32_t calling_uid, const std::string& calling_package);
    RunStatus RetrieveInternal(int32_t calling_uid, const std::string& calling_package,
                                const bool keep_bugreport_on_retrieval);

    RunStatus DumpstateDefaultAfterCritical();
    RunStatus dumpstate();

    void MaybeTakeEarlyScreenshot();
    std::future<std::string> MaybeSnapshotSystemTraceAsync();
    void MaybeWaitForSnapshotSystemTrace(std::future<std::string> task);
    void MaybeSnapshotUiTraces();
    void MaybeAddUiTracesToZip();

    void onUiIntensiveBugreportDumpsFinished(int32_t calling_uid);

    void MaybeCheckUserConsent(int32_t calling_uid, const std::string& calling_package);

    // Removes the in progress files output files (tmp file, zip/txt file, screenshot),
    // but leaves the log file alone.
    void CleanupTmpFiles();

    // Create the thread pool to enable the parallel run function.
    void EnableParallelRunIfNeeded();
    void ShutdownDumpPool();

    RunStatus HandleUserConsentDenied();

    void HandleRunStatus(RunStatus status);

    // Copies bugreport artifacts over to the caller's directories provided there is user consent or
    // called by Shell.
    RunStatus CopyBugreportIfUserConsented(int32_t calling_uid);

    std::function<int(const char *)> open_socket_fn_;

    // Used by GetInstance() only.
    explicit Dumpstate(const std::string& version = VERSION_CURRENT);

    android::sp<ConsentCallback> consent_callback_;

    std::recursive_mutex mutex_;

    DISALLOW_COPY_AND_ASSIGN(Dumpstate);
};

// for_each_pid_func = void (*)(int, const char*);
// for_each_tid_func = void (*)(int, int, const char*);

typedef void(for_each_pid_func)(int, const char*);
typedef void(for_each_tid_func)(int, int, const char*);

/* saves the the contents of a file as a long */
int read_file_as_long(const char *path, long int *output);

/* prints the contents of the fd
 * fd must have been opened with the flag O_NONBLOCK.
 */
int dump_file_from_fd(const char *title, const char *path, int fd);

/* calls skip to gate calling dump_from_fd recursively
 * in the specified directory. dump_from_fd defaults to
 * dump_file_from_fd above when set to NULL. skip defaults
 * to false when set to NULL. dump_from_fd will always be
 * called with title NULL.
 */
int dump_files(const std::string& title, const char* dir, bool (*skip)(const char* path),
               int (*dump_from_fd)(const char* title, const char* path, int fd));

/*
 * Redirects 'redirect' to a file indicated by 'path', truncating it.
 *
 * Returns true if redirect succeeds.
 */
bool redirect_to_file(FILE* redirect, char* path);

/*
 * Redirects 'redirect' to an existing file indicated by 'path', appending it.
 *
 * Returns true if redirect succeeds.
 */
bool redirect_to_existing_file(FILE* redirect, char* path);

/* create leading directories, if necessary */
void create_parent_dirs(const char *path);

/* for each process in the system, run the specified function */
void for_each_pid(for_each_pid_func func, const char *header);

/* for each thread in the system, run the specified function */
void for_each_tid(for_each_tid_func func, const char *header);

/* Displays a blocked processes in-kernel wait channel */
void show_wchan(int pid, int tid, const char *name);

/* Displays a processes times */
void show_showtime(int pid, const char *name);

/* Gets the dmesg output for the kernel */
void do_dmesg();

/* Prints the contents of all the routing tables, both IPv4 and IPv6. */
void dump_route_tables();

/* Dump subdirectories of cgroupfs if the corresponding process is frozen */
void dump_frozen_cgroupfs();

/* Play a sound via Stagefright */
void play_sound(const char *path);

/* Checks if a given path is a directory. */
bool is_dir(const char* pathname);

/** Gets the last modification time of a file, or default time if file is not found. */
time_t get_mtime(int fd, time_t default_mtime);

/** Gets command-line arguments. */
void format_args(int argc, const char *argv[], std::string *args);

/** Main entry point for dumpstate. */
int run_main(int argc, char* argv[]);

#ifdef __cplusplus
}
#endif

#endif /* FRAMEWORK_NATIVE_CMD_DUMPSTATE_H_ */
