/*
 * Copyright (C) 2016 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.
 */
#pragma once

#ifndef SECTIONS_H
#define SECTIONS_H

#include "Reporter.h"

#include <stdarg.h>
#include <map>

#include <android/os/IIncidentDumpCallback.h>

#include <utils/String16.h>
#include <utils/String8.h>
#include <utils/Vector.h>

namespace android {
namespace os {
namespace incidentd {

const int64_t REMOTE_CALL_TIMEOUT_MS = 30 * 1000;  // 30 seconds

/**
 * Base class for sections
 */
class Section {
public:
    const int id;
    const int64_t timeoutMs;  // each section must have a timeout
    String8 name;

    Section(int id, int64_t timeoutMs = REMOTE_CALL_TIMEOUT_MS);
    virtual ~Section();

    virtual status_t Execute(ReportWriter* writer) const = 0;
};

/**
 * Section that reads in a file.
 */
class FileSection : public Section {
public:
    FileSection(int id, const char* filename,
                int64_t timeoutMs = 5000 /* 5 seconds */);
    virtual ~FileSection();

    virtual status_t Execute(ReportWriter* writer) const;

private:
    const char* mFilename;
    bool mIsSysfs;  // sysfs files are pollable but return POLLERR by default, handle it separately
};

/**
 * Section that reads in a file and gzips the content.
 */
class GZipSection : public Section {
public:
    GZipSection(int id, const char* filename, ...);
    virtual ~GZipSection();

    virtual status_t Execute(ReportWriter* writer) const;

private:
    // It looks up the content from multiple files and stops when the first one is available.
    const char** mFilenames;
};

/**
 * Base class for sections that call a command that might need a timeout.
 */
class WorkerThreadSection : public Section {
public:
    WorkerThreadSection(int id, int64_t timeoutMs = REMOTE_CALL_TIMEOUT_MS);
    virtual ~WorkerThreadSection();

    virtual status_t Execute(ReportWriter* writer) const;

    virtual status_t BlockingCall(unique_fd& pipeWriteFd) const = 0;
};

/**
 * Section that forks and execs a command, and puts stdout as the section.
 */
class CommandSection : public Section {
public:
    CommandSection(int id, int64_t timeoutMs, const char* command, ...);

    CommandSection(int id, const char* command, ...);

    virtual ~CommandSection();

    virtual status_t Execute(ReportWriter* writer) const;

private:
    const char** mCommand;
};

/**
 * Section that calls protobuf dumpsys on a system service, usually
 * "dumpsys [service_name] --proto".
 */
class DumpsysSection : public WorkerThreadSection {
public:
    DumpsysSection(int id, const char* service, ...);
    virtual ~DumpsysSection();

    virtual status_t BlockingCall(unique_fd& pipeWriteFd) const;

private:
    String16 mService;
    Vector<String16> mArgs;
};

/**
 * Section that calls text dumpsys on a system service, usually "dumpsys [service_name]".
 */
class TextDumpsysSection : public Section {
public:
    TextDumpsysSection(int id, const char* service, ...);
    virtual ~TextDumpsysSection();

    virtual status_t Execute(ReportWriter* writer) const;

private:
    String16 mService;
    Vector<String16> mArgs;
};

/**
 * Section that calls dumpsys on a system service.
 */
class SystemPropertyDumpsysSection : public WorkerThreadSection {
public:
    SystemPropertyDumpsysSection(int id, const char* service, ...);
    virtual ~SystemPropertyDumpsysSection();

    virtual status_t BlockingCall(unique_fd& pipeWriteFd) const;

private:
    String16 mService;
    Vector<String16> mArgs;
};

/**
 * Section that reads from logd.
 */
class LogSection : public WorkerThreadSection {
    // global last log retrieved timestamp for each log_id_t.
    static map<log_id_t, log_time> gLastLogsRetrieved;

    // log mode: read only & non blocking.
    const static int logModeBase = ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK;

public:
    LogSection(int id, const char* logID, ...);
    virtual ~LogSection();

    virtual status_t BlockingCall(unique_fd& pipeWriteFd) const;

private:
    log_id_t mLogID;
    bool mBinary;
    int mLogMode;
};

/**
 * Section that gets data from tombstoned.
 */
class TombstoneSection : public WorkerThreadSection {
public:
    TombstoneSection(int id, const char* type, int64_t timeoutMs = 120000 /* 2 minutes */);
    virtual ~TombstoneSection();

    virtual status_t BlockingCall(unique_fd& pipeWriteFd) const;

private:
    std::string mType;
};

/**
 * Section that gets data from a registered dump callback.
 */
class BringYourOwnSection : public WorkerThreadSection {
public:
    const uid_t uid;

    BringYourOwnSection(int id, const char* customName, const uid_t callingUid,
        const sp<IIncidentDumpCallback>& callback);
    virtual ~BringYourOwnSection();

    virtual status_t BlockingCall(unique_fd& pipeWriteFd) const;

private:
    const sp<IIncidentDumpCallback>& mCallback;
};


/**
 * These sections will not be generated when doing an 'all' report, either
 * for size, speed of collection, or privacy.
 */
bool section_requires_specific_mention(int sectionId);

}  // namespace incidentd
}  // namespace os
}  // namespace android

#endif  // SECTIONS_H
