/*
 * Copyright (C) 2011 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 "WindowInfo"
#define LOG_NDEBUG 0

#include <type_traits>

#include <binder/Parcel.h>
#include <gui/WindowInfo.h>

#include <log/log.h>

namespace android::gui {

namespace {

constexpr size_t kMaxBytesName = 1024;

// Avoiding pulling in ICU here.
status_t writeUtf8AsUtf16WithTruncation(Parcel* parcel, const std::string& str, size_t max_bytes) {
    if (str.size() <= max_bytes) {
        return parcel->writeUtf8AsUtf16(str);
    }
    std::string truncated;
    truncated.reserve(max_bytes);
    static constexpr std::string_view kTail = "[TRUNC]";
    size_t truncated_length = max_bytes - kTail.size();
    while (truncated_length > 0 &&
           (static_cast<unsigned char>(str[truncated_length]) & 0xC0) == 0x80) {
        truncated_length--;
    }
    truncated.append(str.substr(0, truncated_length));
    truncated.append(kTail);
    return parcel->writeUtf8AsUtf16(truncated);
}

std::ostream& operator<<(std::ostream& out, const sp<IBinder>& binder) {
    if (binder == nullptr) {
        out << "<null>";
    } else {
        out << binder.get();
    }
    return out;
}

std::ostream& operator<<(std::ostream& out, const Region& region) {
    if (region.isEmpty()) {
        out << "<empty>";
        return out;
    }

    bool first = true;
    Region::const_iterator cur = region.begin();
    Region::const_iterator const tail = region.end();
    while (cur != tail) {
        if (first) {
            first = false;
        } else {
            out << "|";
        }
        out << "[" << cur->left << "," << cur->top << "][" << cur->right << "," << cur->bottom
            << "]";
        cur++;
    }
    return out;
}

status_t writeTransform(android::Parcel* parcel, const ui::Transform& transform) {
    return parcel->writeFloat(transform.dsdx()) ?:
            parcel->writeFloat(transform.dtdx()) ?:
            parcel->writeFloat(transform.tx()) ?:
            parcel->writeFloat(transform.dtdy()) ?:
            parcel->writeFloat(transform.dsdy()) ?:
            parcel->writeFloat(transform.ty());
}

status_t readTransform(const android::Parcel* parcel, ui::Transform& transform) {
    float dsdx, dtdx, tx, dtdy, dsdy, ty;

    const status_t status = parcel->readFloat(&dsdx) ?:
            parcel->readFloat(&dtdx) ?:
            parcel->readFloat(&tx) ?:
            parcel->readFloat(&dtdy) ?:
            parcel->readFloat(&dsdy) ?:
            parcel->readFloat(&ty);
    if (status != OK) {
        return status;
    }

    transform.set({dsdx, dtdx, tx, dtdy, dsdy, ty, 0, 0, 1});
    return OK;
}

} // namespace

void WindowInfo::setInputConfig(ftl::Flags<InputConfig> config, bool value) {
    if (value) {
        inputConfig |= config;
        return;
    }
    inputConfig &= ~config;
}

void WindowInfo::addTouchableRegion(const Rect& region) {
    touchableRegion.orSelf(region);
}

bool WindowInfo::isSpy() const {
    return inputConfig.test(InputConfig::SPY);
}

bool WindowInfo::interceptsStylus() const {
    return inputConfig.test(InputConfig::INTERCEPTS_STYLUS);
}

bool WindowInfo::overlaps(const WindowInfo* other) const {
    return !frame.isEmpty() && frame.left < other->frame.right && frame.right > other->frame.left &&
            frame.top < other->frame.bottom && frame.bottom > other->frame.top;
}

bool WindowInfo::operator==(const WindowInfo& info) const {
    return info.token == token && info.id == id && info.name == name &&
            info.dispatchingTimeout == dispatchingTimeout && info.frame == frame &&
            info.contentSize == contentSize && info.surfaceInset == surfaceInset &&
            info.globalScaleFactor == globalScaleFactor && info.transform == transform &&
            info.touchableRegion.hasSameRects(touchableRegion) &&
            info.touchOcclusionMode == touchOcclusionMode && info.ownerPid == ownerPid &&
            info.ownerUid == ownerUid && info.packageName == packageName &&
            info.inputConfig == inputConfig && info.displayId == displayId &&
            info.replaceTouchableRegionWithCrop == replaceTouchableRegionWithCrop &&
            info.applicationInfo == applicationInfo && info.layoutParamsType == layoutParamsType &&
            info.layoutParamsFlags == layoutParamsFlags &&
            info.canOccludePresentation == canOccludePresentation;
}

status_t WindowInfo::writeToParcel(android::Parcel* parcel) const {
    if (parcel == nullptr) {
        ALOGE("%s: Null parcel", __func__);
        return BAD_VALUE;
    }
    if (name.empty()) {
        parcel->writeInt32(0);
        return OK;
    }
    parcel->writeInt32(1);

    // Ensure that the size of custom types are what we expect for writing into the parcel.
    static_assert(sizeof(inputConfig) == 4u);
    static_assert(sizeof(ownerPid.val()) == 4u);
    static_assert(sizeof(ownerUid.val()) == 4u);

    // clang-format off
    status_t status = parcel->writeStrongBinder(token) ?:
        parcel->writeInt64(dispatchingTimeout.count()) ?:
        parcel->writeInt32(id) ?:
        writeUtf8AsUtf16WithTruncation(parcel, name, kMaxBytesName) ?:
        parcel->writeInt32(layoutParamsFlags.get()) ?:
        parcel->writeInt32(
                static_cast<std::underlying_type_t<WindowInfo::Type>>(layoutParamsType)) ?:
        parcel->write(frame) ?:
        parcel->writeInt32(contentSize.width) ?:
        parcel->writeInt32(contentSize.height) ?:
        parcel->writeInt32(surfaceInset) ?:
        parcel->writeFloat(globalScaleFactor) ?:
        parcel->writeFloat(alpha) ?:
        writeTransform(parcel, transform) ?:
        parcel->writeInt32(static_cast<int32_t>(touchOcclusionMode)) ?:
        parcel->writeInt32(ownerPid.val()) ?:
        parcel->writeInt32(ownerUid.val()) ?:
        parcel->writeUtf8AsUtf16(packageName) ?:
        parcel->writeInt32(inputConfig.get()) ?:
        parcel->writeInt32(displayId.val()) ?:
        applicationInfo.writeToParcel(parcel) ?:
        parcel->write(touchableRegion) ?:
        parcel->writeBool(replaceTouchableRegionWithCrop) ?:
        parcel->writeStrongBinder(touchableRegionCropHandle.promote()) ?:
        parcel->writeStrongBinder(windowToken) ?:
        parcel->writeStrongBinder(focusTransferTarget) ?:
        parcel->writeBool(canOccludePresentation) ?:
        parcel->writeBool(cloneLayerStackTransform.has_value());
    // clang-format on
    if (cloneLayerStackTransform) {
        status = status ?: writeTransform(parcel, *cloneLayerStackTransform);
    }
    return status;
}

status_t WindowInfo::readFromParcel(const android::Parcel* parcel) {
    if (parcel == nullptr) {
        ALOGE("%s: Null parcel", __func__);
        return BAD_VALUE;
    }
    if (parcel->readInt32() == 0) {
        return OK;
    }

    token = parcel->readStrongBinder();
    dispatchingTimeout = static_cast<decltype(dispatchingTimeout)>(parcel->readInt64());
    status_t status = parcel->readInt32(&id) ?: parcel->readUtf8FromUtf16(&name);
    if (status != OK) {
        return status;
    }

    int32_t lpFlags, lpType, touchOcclusionModeInt, inputConfigInt, ownerPidInt, ownerUidInt,
            displayIdInt;
    sp<IBinder> touchableRegionCropHandleSp;
    bool hasCloneLayerStackTransform = false;

    // clang-format off
    status = parcel->readInt32(&lpFlags) ?:
        parcel->readInt32(&lpType) ?:
        parcel->read(frame) ?:
        parcel->readInt32(&contentSize.width) ?:
        parcel->readInt32(&contentSize.height) ?:
        parcel->readInt32(&surfaceInset) ?:
        parcel->readFloat(&globalScaleFactor) ?:
        parcel->readFloat(&alpha) ?:
        readTransform(parcel, /*byRef*/ transform) ?:
        parcel->readInt32(&touchOcclusionModeInt) ?:
        parcel->readInt32(&ownerPidInt) ?:
        parcel->readInt32(&ownerUidInt) ?:
        parcel->readUtf8FromUtf16(&packageName) ?:
        parcel->readInt32(&inputConfigInt) ?:
        parcel->readInt32(&displayIdInt) ?:
        applicationInfo.readFromParcel(parcel) ?:
        parcel->read(touchableRegion) ?:
        parcel->readBool(&replaceTouchableRegionWithCrop) ?:
        parcel->readNullableStrongBinder(&touchableRegionCropHandleSp) ?:
        parcel->readNullableStrongBinder(&windowToken) ?:
        parcel->readNullableStrongBinder(&focusTransferTarget) ?:
        parcel->readBool(&canOccludePresentation)?:
        parcel->readBool(&hasCloneLayerStackTransform);
    // clang-format on

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

    layoutParamsFlags = ftl::Flags<Flag>(lpFlags);
    layoutParamsType = static_cast<Type>(lpType);
    touchOcclusionMode = static_cast<TouchOcclusionMode>(touchOcclusionModeInt);
    inputConfig = ftl::Flags<InputConfig>(inputConfigInt);
    ownerPid = Pid{ownerPidInt};
    ownerUid = Uid{static_cast<uid_t>(ownerUidInt)};
    touchableRegionCropHandle = touchableRegionCropHandleSp;
    displayId = ui::LogicalDisplayId{displayIdInt};

    cloneLayerStackTransform =
            hasCloneLayerStackTransform ? std::make_optional<ui::Transform>() : std::nullopt;
    if (cloneLayerStackTransform) {
        status = readTransform(parcel, /*byRef*/ *cloneLayerStackTransform);
        if (status != OK) {
            return status;
        }
    }

    return OK;
}

WindowInfoHandle::WindowInfoHandle() {}

WindowInfoHandle::~WindowInfoHandle() {}

WindowInfoHandle::WindowInfoHandle(const WindowInfoHandle& other) : mInfo(other.mInfo) {}

WindowInfoHandle::WindowInfoHandle(const WindowInfo& other) : mInfo(other) {}

status_t WindowInfoHandle::writeToParcel(android::Parcel* parcel) const {
    return mInfo.writeToParcel(parcel);
}

status_t WindowInfoHandle::readFromParcel(const android::Parcel* parcel) {
    return mInfo.readFromParcel(parcel);
}

void WindowInfoHandle::releaseChannel() {
    mInfo.token.clear();
}

sp<IBinder> WindowInfoHandle::getToken() const {
    return mInfo.token;
}

void WindowInfoHandle::updateFrom(sp<WindowInfoHandle> handle) {
    mInfo = handle->mInfo;
}

std::ostream& operator<<(std::ostream& out, const WindowInfo& info) {
    out << "name=" << info.name << ", id=" << info.id << ", displayId=" << info.displayId
        << ", inputConfig=" << info.inputConfig.string() << ", alpha=" << info.alpha << ", frame=["
        << info.frame.left << "," << info.frame.top << "][" << info.frame.right << ","
        << info.frame.bottom << "], globalScale=" << info.globalScaleFactor
        << ", applicationInfo.name=" << info.applicationInfo.name
        << ", applicationInfo.token=" << info.applicationInfo.token
        << ", touchableRegion=" << info.touchableRegion << ", ownerPid=" << info.ownerPid.toString()
        << ", ownerUid=" << info.ownerUid.toString() << ", dispatchingTimeout="
        << std::chrono::duration_cast<std::chrono::milliseconds>(info.dispatchingTimeout).count()
        << "ms, token=" << info.token.get()
        << ", touchOcclusionMode=" << ftl::enum_string(info.touchOcclusionMode);
    if (info.canOccludePresentation) out << ", canOccludePresentation";
    std::string transform;
    info.transform.dump(transform, "transform", "    ");
    out << "\n" << transform;
    return out;
}

std::ostream& operator<<(std::ostream& out, const WindowInfoHandle& window) {
    const WindowInfo& info = *window.getInfo();
    out << info;
    return out;
}

} // namespace android::gui
