/*
 * Copyright (c) 2015-2018 TRUSTONIC LIMITED
 * All rights reserved
 *
 * The present software is the confidential and proprietary information of
 * TRUSTONIC LIMITED. You shall not disclose the present software and shall
 * use it only in accordance with the terms of the license agreement you
 * entered into with TRUSTONIC LIMITED. This software may be subject to
 * export or import laws in certain countries.
 */

#ifndef DEBUG_INFO_H_
#define DEBUG_INFO_H_

#include <stdlib.h>
#include <ctype.h>
#include <vector>
#include <string>
#include <pthread.h>
#include "mcdebugsession.h"
#include "Utils.h"

class DebugInfo {
public:
    enum Action {
        ALL_INFO,
        ALL_BUT_DBGFS_INFO,
        DBGFS_ALL_INFO,
        DBGFS_LAST_MCP_COMMAND_INFO,
        DBGFS_LAST_IWP_COMMAND_INFO,
        DBGFS_SESSIONS_INFO,
        KERNEL_INFO,
        KERNEL_GROUPED_INFO,
        KERNEL_ORDERED_INFO,
        THREAD_EVENT,
        RTM_INFO,
        UNKNOWN
    };

private:
    std::string             nwd_proc_name_;
    uint8_t                 *debug_info_;
    bool                    is_alloc_;
    debugsession_header_t   *debug_info_header_;
    tee_identity_t          *debug_info_id_;
    tee_kernel_t            *debug_info_kernel_;
    tee_rtm_t               *debug_info_rtm_;
    size_t                  size_;
    int                     debug_session_PID_;
    std::vector<Action>*    actions_;
    bool                    do_top_;
    bool                    do_verbose_;
    bool                    last_update_failed_;
    char                    last_update_date_[DATE_BUFFER_SIZE];

    bool                    stop_;
    pthread_cond_t          cond_;
    pthread_mutex_t         stop_lock_;

    int getDebugSessionPID(std::string proc_name);
    int update();
    int readFile(const char *filename);

    bool isTopStopped();
    void topWait();

    // Show functions spreaded in different files for each functional units.
    // In DebugInfo.cpp
    void showInfo();
    void showProgramHeader();
    void showProductId();
    // In DebugInfo_rtm.cpp
    void showRTMInfo();
    void showSessionInfo(uint32_t index);
    // In DebugInfo_kernel.cpp
    void showKernelInfo(bool ordered);
    void showThreadInfo(uint32_t index);
    void showThreadSysEvents();
    void showThreadSysEvent(uint32_t index);
    void showBasicKernelInfo();
    void showBasicKernelInfoSorted();
    void showGroupedThreadsInfo();
    void dumpEntryExitOneCore(tee_entry_exit_t *pTeeDbgKernelEntryExitCtx, uint32_t frequencyKHz);
    void showCrashes();
    bool dumpOneLine( tee_timestamp_t *ts, uint32_t frequencyKHz, long long unsigned int last_exit, uint32_t core_id);

    // In DebugInfo_fs.cpp
    void showLastMcpCommand();
    void showLastIwpCommand();
    void showMcpSessions();
    void showIwpSessions();
    void showStructs();
    void showSwdDebuggable();
    void showMcpTimeout();

public:
    DebugInfo();
    DebugInfo(const char *filename);
    ~DebugInfo();
    int exec(bool top_behavior, bool do_verbose, std::vector<Action>* act);
    void top();
    void stopTop();
};

#endif /* DEBUG_INFO_H_ */
