/*
 * 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

#include "FdBuffer.h"
#include "Throttler.h"
#include "WorkDirectory.h"

#include "frameworks/base/core/proto/android/os/metadata.pb.h"
#include <android/content/ComponentName.h>
#include <android/os/IIncidentReportStatusListener.h>
#include <android/os/IncidentReportArgs.h>
#include <android/util/protobuf.h>

#include <map>
#include <string>
#include <vector>

#include <time.h>
#include <stdarg.h>

namespace android {
namespace os {
namespace incidentd {

using namespace std;
using namespace android::content;
using namespace android::os;

class Section;

// ================================================================================
class ReportRequest : public virtual RefBase {
public:
    IncidentReportArgs args;

    ReportRequest(const IncidentReportArgs& args, const sp<IIncidentReportStatusListener>& listener,
                  int fd);
    virtual ~ReportRequest();

    bool isStreaming() { return mIsStreaming; }

    void setStatus(status_t err) { mStatus = err; }
    status_t getStatus() const { return mStatus; }

    bool ok();  // returns true if the request is ok for write.

    bool containsSection(int sectionId) const { return args.containsSection(sectionId); }

    sp<IIncidentReportStatusListener> getListener() { return mListener; }

    int getFd() { return mFd; }

    int setPersistedFd(int fd);

    void closeFd();

private:
    sp<IIncidentReportStatusListener> mListener;
    int mFd;
    bool mIsStreaming;
    status_t mStatus;
};

// ================================================================================
class ReportBatch : public virtual RefBase {
public:
    ReportBatch();
    virtual ~ReportBatch();

    // TODO: Should there be some kind of listener associated with the
    // component? Could be good for getting status updates e.g. in the ui,
    // as it progresses.  But that's out of scope for now.

    /**
     * Schedule a report for the "main" report, where it will be delivered to
     * the uploaders and/or dropbox.
     */
    void addPersistedReport(const IncidentReportArgs& args);

    /**
     * Adds a ReportRequest to the queue for one that has a listener an and fd
     */
    void addStreamingReport(const IncidentReportArgs& args,
           const sp<IIncidentReportStatusListener>& listener, int streamFd);

    /**
     * Returns whether both queues are empty.
     */
    bool empty() const;

    /**
     * Returns whether there are any persisted records.
     */
    bool hasPersistedReports() const { return mPersistedRequests.size() > 0; }

    /**
     * Return the persisted request for the given component, or nullptr.
     */
    sp<ReportRequest> getPersistedRequest(const ComponentName& component);

    /**
     * Call func(request) for each Request.
     */
    void forEachPersistedRequest(const function<void (const sp<ReportRequest>&)>& func);

    /**
     * Call func(request) for each Request.
     */
    void forEachStreamingRequest(const function<void (const sp<ReportRequest>&)>& func);

    /**
     * Call func(request) for each file descriptor that has 
     */
    void forEachFd(int sectionId, const function<void (const sp<ReportRequest>&)>& func);

    /**
     * Call func(listener) for every listener in this batch.
     */
    void forEachListener(const function<void (const sp<IIncidentReportStatusListener>&)>& func);

    /**
     * Call func(listener) for every listener in this batch that requests
     * sectionId.
     */
    void forEachListener(int sectionId,
            const function<void (const sp<IIncidentReportStatusListener>&)>& func);
    /**
     * Get an IncidentReportArgs that represents the combined args for the
     * persisted requests.
     */
    void getCombinedPersistedArgs(IncidentReportArgs* results);

    /**
     * Return whether any of the requests contain the section.
     */
    bool containsSection(int id);

    /**
     * Remove all of the broadcast (persisted) requests.
     */
    void clearPersistedRequests();

    /**
     * Get the requests that have encountered errors.
     */
    void getFailedRequests(vector<sp<ReportRequest>>* requests);

    /**
     * Remove the request from whichever list it's in.
     */
    void removeRequest(const sp<ReportRequest>& request);


private:
    map<ComponentName, sp<ReportRequest>> mPersistedRequests;
    vector<sp<ReportRequest>> mStreamingRequests;
};

// ================================================================================
class ReportWriter {
public:
    ReportWriter(const sp<ReportBatch>& batch);
    ~ReportWriter();

    void setPersistedFile(sp<ReportFile> file);
    void setMaxPersistedPrivacyPolicy(uint8_t privacyPolicy);

    void startSection(int sectionId);
    void endSection(IncidentMetadata::SectionStats* sectionStats);

    void setSectionStats(const FdBuffer& buffer);

    void warning(const Section* section, status_t err, const char* format, ...);
    void error(const Section* section, status_t err, const char* format, ...);

    status_t writeSection(const FdBuffer& buffer);

private:
    // Data about all requests
    sp<ReportBatch> mBatch;

    /**
     * The file on disk where we will store the persisted file.
     */
    sp<ReportFile> mPersistedFile;

    /**
     * The least restricted privacy policy of all of the perstited
     * requests. We pre-filter to that to save disk space.
     */
    uint8_t mMaxPersistedPrivacyPolicy;

    /**
     * The current section that is being written.
     */
    int mCurrentSectionId;

    /**
     * The time that that the current section was started.
     */
    int64_t mSectionStartTimeMs;

    /**
     * The last section that setSectionStats was called for, so if someone misses
     * it we can log that.
     */
    int mSectionStatsCalledForSectionId;

    /*
     * Fields for IncidentMetadata.SectionStats.  Set by setSectionStats.  Accessed by
     * getSectionStats.
     */
    int32_t mDumpSizeBytes;
    int64_t mDumpDurationMs;
    bool mSectionTimedOut;
    bool mSectionTruncated;
    bool mSectionBufferSuccess;
    bool mHadError;
    string mSectionErrors;
    size_t mMaxSectionDataFilteredSize;

    void vflog(const Section* section, status_t err, int level, const char* levelText,
        const char* format, va_list args);
};

// ================================================================================
class Reporter : public virtual RefBase {
public:
    Reporter(const sp<WorkDirectory>& workDirectory, const sp<ReportBatch>& batch);

    virtual ~Reporter();

    // Run the report as described in the batch and args parameters.
    void runReport(size_t* reportByteSize);

private:
    sp<WorkDirectory> mWorkDirectory;
    ReportWriter mWriter;
    sp<ReportBatch> mBatch;
    sp<ReportFile> mPersistedFile;

    void cancel_and_remove_failed_requests();
};

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