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

#include <hidl/HidlSupport.h>

#include <unordered_map>

#include <android-base/logging.h>
#include <android-base/parseint.h>
#include <hidl-util/FQName.h>
#include <vintf/VendorManifest.h>
#include <vintf/parse_string.h>

#ifdef LIBHIDL_TARGET_DEBUGGABLE
#include <cutils/properties.h>
#include <dlfcn.h>
#include <regex>
#include <utility>
#endif

namespace android {
namespace hardware {
vintf::Transport getTransportForFrameworkPackages(const std::string &name) {
    // TODO(b/34772739): check with VNDK team to see if this should be in an XML.
    const static std::unordered_map<std::string, vintf::Transport> sTransports {
        {"android.hidl.manager@1.0::IServiceManager", vintf::Transport::HWBINDER},
        {"android.hidl.memory@1.0::IAllocator"      , vintf::Transport::HWBINDER},
        {"android.hidl.memory@1.0::IMapper"         , vintf::Transport::PASSTHROUGH},
        {"android.hidl.memory@1.0::IMemory"         , vintf::Transport::PASSTHROUGH},
    };
    auto it = sTransports.find(name);
    if (it == sTransports.end()) {
        LOG(WARNING) << "getTransportForFrameworkPackages: Cannot find entry "
                     << name << " in the static map.";
        return vintf::Transport::EMPTY;
    } else {
        LOG(INFO) << "getTransportForFrameworkPackages: " << name
                  << " declares transport method " << to_string(it->second);
    }
    return it->second;
}

vintf::Transport getTransportForHals(const FQName &fqName) {
    const std::string package = fqName.package();
    const vintf::VendorManifest *vm = vintf::VendorManifest::Get();
    if (vm == nullptr) {
        LOG(WARNING) << "getTransportFromManifest: Cannot find vendor interface manifest.";
        return vintf::Transport::EMPTY;
    }
    if (!fqName.hasVersion()) {
        LOG(ERROR) << "getTransportFromManifest: " << fqName.string()
                   << " does not specify a version.";
        return vintf::Transport::EMPTY;
    }
    vintf::Transport tr = vm->getTransport(package,
            vintf::Version{fqName.getPackageMajorVersion(), fqName.getPackageMinorVersion()});
    if (tr == vintf::Transport::EMPTY) {
        LOG(WARNING) << "getTransportFromManifest: Cannot find entry "
                     << package << fqName.atVersion() << " in vendor interface manifest.";
    } else {
        LOG(INFO) << "getTransportFromManifest: " << package << fqName.atVersion()
                  << " declares transport method " << to_string(tr);
    }
    return tr;
}

vintf::Transport getTransport(const std::string &name) {
    FQName fqName(name);
    if (!fqName.isValid()) {
        LOG(WARNING) << name << " is not a valid fully-qualified name.";
        return vintf::Transport::EMPTY;
    }
    if (fqName.inPackage("android.hidl")) {
        return getTransportForFrameworkPackages(name);
    }
    return getTransportForHals(fqName);
}

hidl_handle::hidl_handle() {
    mHandle = nullptr;
    mOwnsHandle = false;
}

hidl_handle::~hidl_handle() {
    freeHandle();
}

hidl_handle::hidl_handle(const native_handle_t *handle) {
    mHandle = handle;
    mOwnsHandle = false;
}

// copy constructor.
hidl_handle::hidl_handle(const hidl_handle &other) {
    mOwnsHandle = false;
    *this = other;
}

// move constructor.
hidl_handle::hidl_handle(hidl_handle &&other) {
    mOwnsHandle = false;
    *this = std::move(other);
}

// assignment operators
hidl_handle &hidl_handle::operator=(const hidl_handle &other) {
    if (this == &other) {
        return *this;
    }
    freeHandle();
    if (other.mHandle != nullptr) {
        mHandle = native_handle_clone(other.mHandle);
        if (mHandle == nullptr) {
            LOG(FATAL) << "Failed to clone native_handle in hidl_handle.";
        }
        mOwnsHandle = true;
    } else {
        mHandle = nullptr;
        mOwnsHandle = false;
    }
    return *this;
}

hidl_handle &hidl_handle::operator=(const native_handle_t *native_handle) {
    freeHandle();
    mHandle = native_handle;
    mOwnsHandle = false;
    return *this;
}

hidl_handle &hidl_handle::operator=(hidl_handle &&other) {
    if (this != &other) {
        freeHandle();
        mHandle = other.mHandle;
        mOwnsHandle = other.mOwnsHandle;
        other.mHandle = nullptr;
        other.mOwnsHandle = false;
    }
    return *this;
}

void hidl_handle::setTo(native_handle_t* handle, bool shouldOwn) {
    mHandle = handle;
    mOwnsHandle = shouldOwn;
}

const native_handle_t* hidl_handle::operator->() const {
    return mHandle;
}

// implicit conversion to const native_handle_t*
hidl_handle::operator const native_handle_t *() const {
    return mHandle;
}

// explicit conversion
const native_handle_t *hidl_handle::getNativeHandle() const {
    return mHandle;
}

void hidl_handle::freeHandle() {
    if (mOwnsHandle && mHandle != nullptr) {
        // This can only be true if:
        // 1. Somebody called setTo() with shouldOwn=true, so we know the handle
        //    wasn't const to begin with.
        // 2. Copy/assignment from another hidl_handle, in which case we have
        //    cloned the handle.
        // 3. Move constructor from another hidl_handle, in which case the original
        //    hidl_handle must have been non-const as well.
        native_handle_t *handle = const_cast<native_handle_t*>(
                static_cast<const native_handle_t*>(mHandle));
        native_handle_close(handle);
        native_handle_delete(handle);
        mHandle = nullptr;
    }
}

static const char *const kEmptyString = "";

hidl_string::hidl_string()
    : mBuffer(kEmptyString),
      mSize(0),
      mOwnsBuffer(false) {
}

hidl_string::~hidl_string() {
    clear();
}

hidl_string::hidl_string(const char *s) : hidl_string() {
    copyFrom(s, strlen(s));
}

hidl_string::hidl_string(const char *s, size_t length) : hidl_string() {
    copyFrom(s, length);
}

hidl_string::hidl_string(const hidl_string &other): hidl_string() {
    copyFrom(other.c_str(), other.size());
}

hidl_string::hidl_string(const std::string &s) : hidl_string() {
    copyFrom(s.c_str(), s.size());
}

hidl_string::hidl_string(hidl_string &&other): hidl_string() {
    moveFrom(std::forward<hidl_string>(other));
}

hidl_string &hidl_string::operator=(hidl_string &&other) {
    if (this != &other) {
        clear();
        moveFrom(std::forward<hidl_string>(other));
    }
    return *this;
}

hidl_string &hidl_string::operator=(const hidl_string &other) {
    if (this != &other) {
        clear();
        copyFrom(other.c_str(), other.size());
    }

    return *this;
}

hidl_string &hidl_string::operator=(const char *s) {
    clear();
    copyFrom(s, strlen(s));
    return *this;
}

hidl_string &hidl_string::operator=(const std::string &s) {
    clear();
    copyFrom(s.c_str(), s.size());
    return *this;
}

hidl_string::operator std::string() const {
    return std::string(mBuffer, mSize);
}

hidl_string::operator const char *() const {
    return mBuffer;
}

void hidl_string::copyFrom(const char *data, size_t size) {
    // assume my resources are freed.

    if (size > UINT32_MAX) {
        LOG(FATAL) << "string size can't exceed 2^32 bytes.";
    }
    char *buf = (char *)malloc(size + 1);
    memcpy(buf, data, size);
    buf[size] = '\0';
    mBuffer = buf;

    mSize = static_cast<uint32_t>(size);
    mOwnsBuffer = true;
}

void hidl_string::moveFrom(hidl_string &&other) {
    // assume my resources are freed.

    mBuffer = other.mBuffer;
    mSize = other.mSize;
    mOwnsBuffer = other.mOwnsBuffer;

    other.mOwnsBuffer = false;
}

void hidl_string::clear() {
    if (mOwnsBuffer && (mBuffer != kEmptyString)) {
        free(const_cast<char *>(static_cast<const char *>(mBuffer)));
    }

    mBuffer = kEmptyString;
    mSize = 0;
    mOwnsBuffer = false;
}

void hidl_string::setToExternal(const char *data, size_t size) {
    if (size > UINT32_MAX) {
        LOG(FATAL) << "string size can't exceed 2^32 bytes.";
    }
    clear();

    mBuffer = data;
    mSize = static_cast<uint32_t>(size);
    mOwnsBuffer = false;
}

const char *hidl_string::c_str() const {
    return mBuffer;
}

size_t hidl_string::size() const {
    return mSize;
}

bool hidl_string::empty() const {
    return mSize == 0;
}

// ----------------------------------------------------------------------
// HidlInstrumentor implementation.
HidlInstrumentor::HidlInstrumentor(
        const std::string &package,
        const std::string &interface)
        : mInstrumentationLibPackage(package), mInterfaceName(interface) {
    configureInstrumentation(false);
}

HidlInstrumentor:: ~HidlInstrumentor() {}

void HidlInstrumentor::configureInstrumentation(bool log) {
    bool enable_instrumentation = property_get_bool(
            "hal.instrumentation.enable",
            false);
    if (enable_instrumentation != mEnableInstrumentation) {
        mEnableInstrumentation = enable_instrumentation;
        if (mEnableInstrumentation) {
            if (log) {
                LOG(INFO) << "Enable instrumentation.";
            }
            registerInstrumentationCallbacks (&mInstrumentationCallbacks);
        } else {
            if (log) {
                LOG(INFO) << "Disable instrumentation.";
            }
            mInstrumentationCallbacks.clear();
        }
    }
}

void HidlInstrumentor::registerInstrumentationCallbacks(
        std::vector<InstrumentationCallback> *instrumentationCallbacks) {
#ifdef LIBHIDL_TARGET_DEBUGGABLE
    std::vector<std::string> instrumentationLibPaths;
    char instrumentation_lib_path[PROPERTY_VALUE_MAX];
    if (property_get("hal.instrumentation.lib.path",
                     instrumentation_lib_path,
                     "") > 0) {
        instrumentationLibPaths.push_back(instrumentation_lib_path);
    } else {
        instrumentationLibPaths.push_back(HAL_LIBRARY_PATH_SYSTEM);
        instrumentationLibPaths.push_back(HAL_LIBRARY_PATH_VENDOR);
        instrumentationLibPaths.push_back(HAL_LIBRARY_PATH_ODM);
    }

    for (auto path : instrumentationLibPaths) {
        DIR *dir = opendir(path.c_str());
        if (dir == 0) {
            LOG(WARNING) << path << " does not exist. ";
            return;
        }

        struct dirent *file;
        while ((file = readdir(dir)) != NULL) {
            if (!isInstrumentationLib(file))
                continue;

            void *handle = dlopen((path + file->d_name).c_str(), RTLD_NOW);
            char *error;
            if (handle == nullptr) {
                LOG(WARNING) << "couldn't load file: " << file->d_name
                    << " error: " << dlerror();
                continue;
            }

            dlerror(); /* Clear any existing error */

            using cb_fun = void (*)(
                    const InstrumentationEvent,
                    const char *,
                    const char *,
                    const char *,
                    const char *,
                    std::vector<void *> *);
            FQName package_name = FQName(mInstrumentationLibPackage);
            auto cb = (cb_fun)dlsym(handle, ("HIDL_INSTRUMENTATION_FUNCTION_"
                        + package_name.tokenName() + "_"
                        + mInterfaceName).c_str());
            if ((error = dlerror()) != NULL) {
                LOG(WARNING)
                    << "couldn't find symbol: HIDL_INSTRUMENTATION_FUNCTION_"
                    << mInterfaceName << ", error: " << error;
                continue;
            }
            instrumentationCallbacks->push_back(cb);
            LOG(INFO) << "Register instrumentation callback from "
                << file->d_name;
        }
        closedir(dir);
    }
#else
    // No-op for user builds.
    return;
#endif
}

bool HidlInstrumentor::isInstrumentationLib(const dirent *file) {
#ifdef LIBHIDL_TARGET_DEBUGGABLE
    if (file->d_type != DT_REG) return false;
    std::cmatch cm;
    std::regex e("^" + mInstrumentationLibPackage + "(.*).profiler.so$");
    if (std::regex_match(file->d_name, cm, e)) return true;
#endif
    return false;
}

}  // namespace hardware
}  // namespace android


