/*
 * Copyright (C) 2019 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 STATSD_DEBUG false  // STOPSHIP if true
#include "Log.h"

#include "StatsCallbackPuller.h"
#include "PullResultReceiver.h"
#include "StatsPullerManager.h"
#include "logd/LogEvent.h"
#include "stats_log_util.h"

#include <aidl/android/util/StatsEventParcel.h>

using namespace std;

using Status = ::ndk::ScopedAStatus;
using aidl::android::util::StatsEventParcel;
using ::ndk::SharedRefBase;

namespace android {
namespace os {
namespace statsd {

StatsCallbackPuller::StatsCallbackPuller(int tagId, const shared_ptr<IPullAtomCallback>& callback,
                                         const int64_t coolDownNs, int64_t timeoutNs,
                                         const vector<int> additiveFields)
    : StatsPuller(tagId, coolDownNs, timeoutNs, additiveFields), mCallback(callback) {
    VLOG("StatsCallbackPuller created for tag %d", tagId);
}

PullErrorCode StatsCallbackPuller::PullInternal(vector<shared_ptr<LogEvent>>* data) {
    VLOG("StatsCallbackPuller called for tag %d", mTagId);
    if(mCallback == nullptr) {
        ALOGW("No callback registered");
        return PULL_FAIL;
    }

    // Shared variables needed in the result receiver.
    shared_ptr<mutex> cv_mutex = make_shared<mutex>();
    shared_ptr<condition_variable> cv = make_shared<condition_variable>();
    shared_ptr<bool> pullFinish = make_shared<bool>(false);
    shared_ptr<bool> pullSuccess = make_shared<bool>(false);
    shared_ptr<vector<shared_ptr<LogEvent>>> sharedData =
            make_shared<vector<shared_ptr<LogEvent>>>();

    shared_ptr<PullResultReceiver> resultReceiver = SharedRefBase::make<PullResultReceiver>(
            [cv_mutex, cv, pullFinish, pullSuccess, sharedData](
                    int32_t atomTag, bool success, const vector<StatsEventParcel>& output) {
                // This is the result of the pull, executing in a statsd binder thread.
                // The pull could have taken a long time, and we should only modify
                // data (the output param) if the pointer is in scope and the pull did not time out.
                {
                    lock_guard<mutex> lk(*cv_mutex);
                    for (const StatsEventParcel& parcel: output) {
                        shared_ptr<LogEvent> event = make_shared<LogEvent>(/*uid=*/-1, /*pid=*/-1);
                        bool valid = event->parseBuffer((uint8_t*)parcel.buffer.data(),
                                                        parcel.buffer.size());
                        if (valid) {
                            sharedData->push_back(event);
                        } else {
                            StatsdStats::getInstance().noteAtomError(event->GetTagId(),
                                                                     /*pull=*/true);
                        }
                    }
                    *pullSuccess = success;
                    *pullFinish = true;
                }
                cv->notify_one();
            });

    // Initiate the pull. This is a oneway call to a different process, except
    // in unit tests. In process calls are not oneway.
    Status status = mCallback->onPullAtom(mTagId, resultReceiver);
    if (!status.isOk()) {
        StatsdStats::getInstance().notePullBinderCallFailed(mTagId);
        if (status.getExceptionCode() == EX_TRANSACTION_FAILED &&
            status.getStatus() == STATUS_DEAD_OBJECT) {
            return PULL_DEAD_OBJECT;
        }
        return PULL_FAIL;
    }

    {
        unique_lock<mutex> unique_lk(*cv_mutex);
        // Wait until the pull finishes, or until the pull timeout.
        cv->wait_for(unique_lk, chrono::nanoseconds(mPullTimeoutNs),
                     [pullFinish] { return *pullFinish; });
        if (!*pullFinish) {
            // Note: The parent stats puller will also note that there was a timeout and that the
            // cache should be cleared. Once we migrate all pullers to this callback, we could
            // consolidate the logic.
            return PULL_SUCCESS;
        } else {
            // Only copy the data if we did not timeout and the pull was successful.
            if (*pullSuccess) {
                *data = std::move(*sharedData);
            }
            VLOG("StatsCallbackPuller::pull succeeded for %d", mTagId);
            return *pullSuccess ? PULL_SUCCESS : PULL_FAIL;
        }
    }
}

}  // namespace statsd
}  // namespace os
}  // namespace android
