/*
 * Copyright (C) 2017 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 <hidladapter/HidlBinderAdapter.h>

#include <android/hidl/base/1.0/IBase.h>
#include <android/hidl/manager/1.0/IServiceManager.h>
#include <hidl/HidlTransportSupport.h>

#include <iostream>
#include <map>
#include <string>

namespace android {
namespace hardware {
namespace details {

int adapterMain(const std::string& package, int argc, char** argv,
                const AdaptersFactory& adapters) {
    using android::hardware::configureRpcThreadpool;
    using android::hidl::base::V1_0::IBase;
    using android::hidl::manager::V1_0::IServiceManager;

    if (argc != 4) {
        std::cerr << "usage: " << argv[0] << " interface-name instance-name number-of-threads."
                  << std::endl;
        return 1;
    }

    std::string interfaceName = package + "::" + argv[1];
    std::string instanceName = argv[2];
    int threadNumber = std::stoi(argv[3]);

    if (threadNumber <= 0) {
        std::cerr << "ERROR: invalid thread number " << threadNumber
                  << " must be a positive integer.";
    }

    auto it = adapters.find(interfaceName);
    if (it == adapters.end()) {
        std::cerr << "ERROR: could not resolve " << interfaceName << "." << std::endl;
        return 1;
    }

    std::cout << "Trying to adapt down " << interfaceName << "/" << instanceName << std::endl;

    configureRpcThreadpool(threadNumber, false /* callerWillJoin */);

    sp<IServiceManager> manager = IServiceManager::getService();
    if (manager == nullptr) {
        std::cerr << "ERROR: could not retrieve service manager." << std::endl;
        return 1;
    }

    sp<IBase> implementation = manager->get(interfaceName, instanceName).withDefault(nullptr);
    if (implementation == nullptr) {
        std::cerr << "ERROR: could not retrieve desired implementation" << std::endl;
        return 1;
    }

    sp<IBase> adapter = it->second(implementation);
    if (adapter == nullptr) {
        std::cerr << "ERROR: could not create adapter." << std::endl;
        return 1;
    }

    bool replaced = manager->add(instanceName, adapter).withDefault(false);
    if (!replaced) {
        std::cerr << "ERROR: could not register the service with the service manager." << std::endl;
        return 1;
    }

    std::cout << "Press any key to disassociate adapter." << std::endl;
    getchar();

    bool restored = manager->add(instanceName, implementation).withDefault(false);
    if (!restored) {
        std::cerr << "ERROR: could not re-register interface with the service manager."
                  << std::endl;
        return 1;
    }

    std::cout << "Success." << std::endl;

    return 0;
}

// If an interface is adapted to 1.0, it can then not be adapted to 1.1 in the same process.
// This poses a problem in the following scenario:
// auto interface = new V1_1::implementation::IFoo;
// hidlObject1_0->foo(interface) // adaptation set at 1.0
// hidlObject1_1->bar(interface) // adaptation still is 1.0
// This could be solved by keeping a map of IBase,fqName -> IBase, but then you end up
// with multiple names for the same interface.
sp<IBase> adaptWithDefault(const sp<IBase>& something,
                           const std::function<sp<IBase>()>& makeDefault) {
    static std::map<sp<IBase>, sp<IBase>> sAdapterMap;

    if (something == nullptr) {
        return something;
    }

    auto it = sAdapterMap.find(something);
    if (it == sAdapterMap.end()) {
        it = sAdapterMap.insert(it, {something, makeDefault()});
    }

    return it->second;
}

}  // namespace details
}  // namespace hardware
}  // namespace android
