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

#define LOG_TAG "dumpstate"

#include <android/os/IncidentReportArgs.h>

#include <log/log.h>

namespace android {
namespace os {

IncidentReportArgs::IncidentReportArgs()
    :mSections(),
     mAll(false),
     mDest(-1)
{
}

IncidentReportArgs::IncidentReportArgs(const IncidentReportArgs& that)
    :mSections(that.mSections),
     mHeaders(that.mHeaders),
     mAll(that.mAll),
     mDest(that.mDest)
{
}

IncidentReportArgs::~IncidentReportArgs()
{
}

status_t
IncidentReportArgs::writeToParcel(Parcel* out) const
{
    status_t err;

    err = out->writeInt32(mAll);
    if (err != NO_ERROR) {
        return err;
    }

    err = out->writeInt32(mSections.size());
    if (err != NO_ERROR) {
        return err;
    }

    for (set<int>::const_iterator it=mSections.begin(); it!=mSections.end(); it++) {
        err = out->writeInt32(*it);
        if (err != NO_ERROR) {
            return err;
        }
    }

    err = out->writeInt32(mHeaders.size());
    if (err != NO_ERROR) {
        return err;
    }

    for (vector<vector<uint8_t>>::const_iterator it = mHeaders.begin(); it != mHeaders.end(); it++) {
        err = out->writeByteVector(*it);
        if (err != NO_ERROR) {
            return err;
        }
    }

    err = out->writeInt32(mDest);
    if (err != NO_ERROR) {
        return err;
    }

    return NO_ERROR;
}

status_t
IncidentReportArgs::readFromParcel(const Parcel* in)
{
    status_t err;

    int32_t all;
    err = in->readInt32(&all);
    if (err != NO_ERROR) {
        return err;
    }
    if (all != 0) {
        mAll = all;
    }

    mSections.clear();
    int32_t sectionCount;
    err = in->readInt32(&sectionCount);
    if (err != NO_ERROR) {
        return err;
    }
    for (int i=0; i<sectionCount; i++) {
        int32_t section;
        err = in->readInt32(&section);
        if (err != NO_ERROR) {
            return err;
        }

        mSections.insert(section);
    }

    int32_t headerCount;
    err = in->readInt32(&headerCount);
    if (err != NO_ERROR) {
        return err;
    }
    mHeaders.resize(headerCount);
    for (int i=0; i<headerCount; i++) {
        err = in->readByteVector(&mHeaders[i]);
        if (err != NO_ERROR) {
            return err;
        }
    }

    int32_t dest;
    err = in->readInt32(&dest);
    if (err != NO_ERROR) {
        return err;
    }
    mDest = dest;

    return OK;
}

void
IncidentReportArgs::setAll(bool all)
{
    mAll = all;
    if (all) {
        mSections.clear();
    }
}

void
IncidentReportArgs::setDest(int dest)
{
    mDest = dest;
}

void
IncidentReportArgs::addSection(int section)
{
    if (!mAll) {
        mSections.insert(section);
    }
}

void
IncidentReportArgs::addHeader(const vector<uint8_t>& headerProto)
{
    mHeaders.push_back(headerProto);
}

bool
IncidentReportArgs::containsSection(int section) const
{
     return mAll || mSections.find(section) != mSections.end();
}

void
IncidentReportArgs::merge(const IncidentReportArgs& that)
{
    if (mAll) {
        return;
    } else if (that.mAll) {
        mAll = true;
        mSections.clear();
    } else {
        for (set<int>::const_iterator it=that.mSections.begin();
                it!=that.mSections.end(); it++) {
            mSections.insert(*it);
        }
    }
}

}
}
