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

#include <hidl/HidlTransportSupport.h>
#include <sys/wait.h>
#include <utils/Log.h>
#include <utils/Errors.h>
#include <utils/StrongPointer.h>

#ifndef ANDROID_HIDL_LEGACY_SUPPORT_H
#define ANDROID_HIDL_LEGACY_SUPPORT_H

namespace android {
namespace hardware {

namespace details {
bool blockingHalBinderizationEnabled();
void blockIfBinderizationDisabled(const std::string& interface,
                                  const std::string& instance);
} // namespace details

/**
 * Registers passthrough service implementation.
 */
template<class Interface>
status_t registerPassthroughServiceImplementation(
        std::string name = "default") {
    // TODO(b/34274385)
    // If binderization is enabled, we should start up. Otherwise, wait around.
    // If we return/kill ourselves, we will just be restarted by init. This
    // function is only called from thin wrapping services, so blocking won't
    // stop anything important from happening.
    details::blockIfBinderizationDisabled(Interface::descriptor, name);

    sp<Interface> service = Interface::getService(name, true /* getStub */);

    if (service == nullptr) {
        ALOGE("Could not get passthrough implementation for %s.", name.c_str());
        return EXIT_FAILURE;
    }

    LOG_FATAL_IF(service->isRemote(), "Implementation of %s is remote!", name.c_str());

    status_t status = service->registerAsService(name);

    if (status == OK) {
        ALOGI("Registration complete for %s.", name.c_str());
    } else {
        ALOGE("Could not register service %s (%d).", name.c_str(), status);
    }

    return status;
}

/**
 * Creates default passthrough service implementation. This method never returns.
 *
 * Return value is exit status.
 */
template<class Interface>
int defaultPassthroughServiceImplementation(std::string name = "default",
                                            size_t maxThreads = 1) {
    configureRpcThreadpool(maxThreads, true);
    status_t result = registerPassthroughServiceImplementation<Interface>(name);

    if (result != OK) {
        return result;
    }

    joinRpcThreadpool();
    return 0;
}

}  // namespace hardware
}  // namespace android

#endif  // ANDROID_HIDL_LEGACY_SUPPORT_H
