/*
 * Copyright (C) 2012-2020 Apple Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 * THE POSSIBILITY OF SUCH DAMAGE.
 */

#import "config.h"
#import "ObjCObjectGraph.h"

#import "ArgumentCodersCocoa.h"
#import "Decoder.h"
#import "Encoder.h"
#import "UserData.h"
#import "WKAPICast.h"
#import "WKBrowsingContextHandleInternal.h"
#import "WKTypeRefWrapper.h"
#import <wtf/EnumTraits.h>
#import <wtf/cocoa/TypeCastsCocoa.h>

namespace WebKit {

static bool shouldTransformGraph(id object, const ObjCObjectGraph::Transformer& transformer)
{
    if (NSArray *array = dynamic_objc_cast<NSArray>(object)) {
        for (id element in array) {
            if (shouldTransformGraph(element, transformer))
                return true;
        }
    }

    if (NSDictionary *dictionary = dynamic_objc_cast<NSDictionary>(object)) {
        bool result = false;
        [dictionary enumerateKeysAndObjectsUsingBlock:[&transformer, &result](id key, id object, BOOL* stop) {
            if (shouldTransformGraph(object, transformer)) {
                result = true;
                *stop = YES;
            }
        }];

        return result;
    }

    return transformer.shouldTransformObject(object);
}

static RetainPtr<id> transformGraph(id object, const ObjCObjectGraph::Transformer& transformer)
{
    if (NSArray *array = dynamic_objc_cast<NSArray>(object)) {
        auto result = adoptNS([[NSMutableArray alloc] initWithCapacity:array.count]);
        for (id element in array)
            [result addObject:transformGraph(element, transformer).get()];

        return result;
    }

    if (NSDictionary *dictionary = dynamic_objc_cast<NSDictionary>(object)) {
        auto result = adoptNS([[NSMutableDictionary alloc] initWithCapacity:dictionary.count]);
        [dictionary enumerateKeysAndObjectsUsingBlock:[&result, &transformer](id key, id object, BOOL*) {
            [result setObject:transformGraph(object, transformer).get() forKey:key];
        }];

        return result;
    }

    return transformer.transformObject(object);
}

RetainPtr<id> ObjCObjectGraph::transform(id object, const Transformer& transformer)
{
    if (!object)
        return nullptr;

    if (!shouldTransformGraph(object, transformer))
        return object;

    return transformGraph(object, transformer);
}

enum class ObjCType : uint8_t {
    Null,

    NSArray,
    NSData,
    NSDate,
    NSDictionary,
    NSNumber,
    NSString,

    WKBrowsingContextHandle,
    WKTypeRefWrapper,
};

static std::optional<ObjCType> typeFromObject(id object)
{
    ASSERT(object);

    if (dynamic_objc_cast<NSArray>(object))
        return ObjCType::NSArray;
    if (dynamic_objc_cast<NSData>(object))
        return ObjCType::NSData;
    if (dynamic_objc_cast<NSDate>(object))
        return ObjCType::NSDate;
    if (dynamic_objc_cast<NSDictionary>(object))
        return ObjCType::NSDictionary;
    if (dynamic_objc_cast<NSNumber>(object))
        return ObjCType::NSNumber;
    if (dynamic_objc_cast<NSString>(object))
        return ObjCType::NSString;

    if (dynamic_objc_cast<WKBrowsingContextHandle>(object))
        return ObjCType::WKBrowsingContextHandle;
    ALLOW_DEPRECATED_DECLARATIONS_BEGIN
    if (dynamic_objc_cast<WKTypeRefWrapper>(object))
        return ObjCType::WKTypeRefWrapper;
    ALLOW_DEPRECATED_DECLARATIONS_END

    return std::nullopt;
}

void ObjCObjectGraph::encode(IPC::Encoder& encoder, id object)
{
    if (!object) {
        encoder << static_cast<uint32_t>(ObjCType::Null);
        return;
    }

    auto type = typeFromObject(object);
    if (!type)
        [NSException raise:NSInvalidArgumentException format:@"Can not encode objects of class type '%@'", static_cast<NSString *>(NSStringFromClass([object class]))];

    encoder << *type;

    switch (type.value()) {
    case ObjCType::Null:
        return;

    case ObjCType::NSArray: {
        NSArray *array = object;

        encoder << static_cast<uint64_t>(array.count);
        for (id element in array)
            encode(encoder, element);
        return;
    }

    case ObjCType::NSData: {
        IPC::encode(encoder, static_cast<NSData *>(object));
        return;
    }

    case ObjCType::NSDate: {
        IPC::encode(encoder, static_cast<NSDate *>(object));
        return;
    }

    case ObjCType::NSDictionary: {
        NSDictionary *dictionary = object;

        encoder << static_cast<uint64_t>(dictionary.count);
        [dictionary enumerateKeysAndObjectsUsingBlock:[&encoder](id key, id object, BOOL *stop) {
            encode(encoder, key);
            encode(encoder, object);
        }];
        return;
    }

    case ObjCType::NSNumber: {
        IPC::encode(encoder, static_cast<NSNumber *>(object));
        return;
    }

    case ObjCType::NSString: {
        IPC::encode(encoder, static_cast<NSString *>(object));
        return;
    }

    case ObjCType::WKBrowsingContextHandle: {
        encoder << static_cast<WKBrowsingContextHandle *>(object).pageProxyID;
        encoder << static_cast<WKBrowsingContextHandle *>(object).webPageID;
        return;
    }

    case ObjCType::WKTypeRefWrapper: {
        ALLOW_DEPRECATED_DECLARATIONS_BEGIN
        UserData::encode(encoder, toImpl(static_cast<WKTypeRefWrapper *>(object).object));
        ALLOW_DEPRECATED_DECLARATIONS_END
        return;
    }
    }

    ASSERT_NOT_REACHED();
}

void ObjCObjectGraph::encode(IPC::Encoder& encoder) const
{
    encode(encoder, m_rootObject.get());
}

bool ObjCObjectGraph::decode(IPC::Decoder& decoder, RetainPtr<id>& result)
{
    ObjCType type;
    if (!decoder.decode(type))
        return false;

    switch (type) {
    case ObjCType::Null: {
        result = nil;
        return true;
    }

    case ObjCType::NSArray: {
        uint64_t size;
        if (!decoder.decode(size))
            return false;

        auto array = adoptNS([[NSMutableArray alloc] init]);
        for (uint64_t i = 0; i < size; ++i) {
            RetainPtr<id> element;
            if (!decode(decoder, element))
                return false;
            [array addObject:element.get()];
        }

        result = WTFMove(array);
        return true;
    }

    case ObjCType::NSData: {
        RetainPtr<NSData> data;
        if (!IPC::decode(decoder, data))
            return false;

        result = WTFMove(data);
        return true;
    }

    case ObjCType::NSDate: {
        RetainPtr<NSDate> date;
        if (!IPC::decode(decoder, date))
            return false;

        result = WTFMove(date);
        return true;
    }

    case ObjCType::NSDictionary: {
        uint64_t size;
        if (!decoder.decode(size))
            return false;

        auto dictionary = adoptNS([[NSMutableDictionary alloc] init]);
        for (uint64_t i = 0; i < size; ++i) {
            RetainPtr<id> key;
            if (!decode(decoder, key))
                return false;

            RetainPtr<id> object;
            if (!decode(decoder, object))
                return false;

            @try {
                [dictionary setObject:object.get() forKey:key.get()];
            } @catch (id) {
                return false;
            }
        }

        result = WTFMove(dictionary);
        return true;
    }

    case ObjCType::NSNumber: {
        RetainPtr<NSNumber> number;
        if (!IPC::decode(decoder, number))
            return false;

        result = WTFMove(number);
        return true;
    }

    case ObjCType::NSString: {
        RetainPtr<NSString> string;
        if (!IPC::decode(decoder, string))
            return false;

        result = WTFMove(string);
        return true;
    }

    case ObjCType::WKBrowsingContextHandle: {
        std::optional<WebPageProxyIdentifier> pageProxyID;
        decoder >> pageProxyID;
        if (!pageProxyID)
            return false;
        std::optional<WebCore::PageIdentifier> webPageID;
        decoder >> webPageID;
        if (!webPageID)
            return false;

        result = adoptNS([[WKBrowsingContextHandle alloc] _initWithPageProxyID:*pageProxyID andWebPageID:*webPageID]);
        return true;
    }

    case ObjCType::WKTypeRefWrapper: {
        RefPtr<API::Object> object;
        if (!UserData::decode(decoder, object))
            return false;

        ALLOW_DEPRECATED_DECLARATIONS_BEGIN
        result = adoptNS([[WKTypeRefWrapper alloc] initWithObject:toAPI(object.get())]);
        ALLOW_DEPRECATED_DECLARATIONS_END
        return true;
    }
    }

    ASSERT_NOT_REACHED();
    return false;
}

bool ObjCObjectGraph::decode(IPC::Decoder& decoder, RefPtr<API::Object>& result)
{
    RetainPtr<id> rootObject;
    if (!decode(decoder, rootObject))
        return false;

    result = ObjCObjectGraph::create(rootObject.get());
    return true;
}

} // namespace WebKit

namespace WTF {

template<> struct EnumTraits<WebKit::ObjCType> {
    using values = EnumValues<
        WebKit::ObjCType,
        WebKit::ObjCType::Null,
        WebKit::ObjCType::NSArray,
        WebKit::ObjCType::NSData,
        WebKit::ObjCType::NSDate,
        WebKit::ObjCType::NSDictionary,
        WebKit::ObjCType::NSNumber,
        WebKit::ObjCType::NSString,
        WebKit::ObjCType::WKBrowsingContextHandle,
        WebKit::ObjCType::WKTypeRefWrapper
    >;
};

} // namespace WTF
