// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "modules/csspaint/PaintWorkletGlobalScope.h"

#include "bindings/core/v8/V8BindingMacros.h"
#include "bindings/core/v8/WorkerOrWorkletScriptController.h"
#include "core/CSSPropertyNames.h"
#include "core/css/parser/CSSVariableParser.h"
#include "core/dom/ExceptionCode.h"
#include "core/inspector/MainThreadDebugger.h"
#include "modules/csspaint/CSSPaintDefinition.h"
#include "modules/csspaint/CSSPaintImageGeneratorImpl.h"

namespace blink {

// static
PaintWorkletGlobalScope* PaintWorkletGlobalScope::create(LocalFrame* frame, const KURL& url, const String& userAgent, PassRefPtr<SecurityOrigin> securityOrigin, v8::Isolate* isolate)
{
    PaintWorkletGlobalScope* paintWorkletGlobalScope = new PaintWorkletGlobalScope(frame, url, userAgent, securityOrigin, isolate);
    paintWorkletGlobalScope->scriptController()->initializeContextIfNeeded();
    MainThreadDebugger::instance()->contextCreated(paintWorkletGlobalScope->scriptController()->getScriptState(), paintWorkletGlobalScope->frame(), paintWorkletGlobalScope->getSecurityOrigin());
    return paintWorkletGlobalScope;
}

PaintWorkletGlobalScope::PaintWorkletGlobalScope(LocalFrame* frame, const KURL& url, const String& userAgent, PassRefPtr<SecurityOrigin> securityOrigin, v8::Isolate* isolate)
    : MainThreadWorkletGlobalScope(frame, url, userAgent, securityOrigin, isolate)
{
}

PaintWorkletGlobalScope::~PaintWorkletGlobalScope()
{
}

void PaintWorkletGlobalScope::dispose()
{
    // Explicitly clear the paint defininitions to break a reference cycle
    // between them and this global scope.
    m_paintDefinitions.clear();

    WorkletGlobalScope::dispose();
}

void PaintWorkletGlobalScope::registerPaint(const String& name, const ScriptValue& ctorValue, ExceptionState& exceptionState)
{
    if (m_paintDefinitions.contains(name)) {
        exceptionState.throwDOMException(NotSupportedError, "A class with name:'" + name + "' is already registered.");
        return;
    }

    if (name.isEmpty()) {
        exceptionState.throwTypeError("The empty string is not a valid name.");
        return;
    }

    v8::Isolate* isolate = scriptController()->getScriptState()->isolate();
    v8::Local<v8::Context> context = scriptController()->context();

    ASSERT(ctorValue.v8Value()->IsFunction());
    v8::Local<v8::Function> constructor = v8::Local<v8::Function>::Cast(ctorValue.v8Value());

    v8::Local<v8::Value> inputPropertiesValue;
    if (!v8Call(constructor->Get(context, v8String(isolate, "inputProperties")), inputPropertiesValue))
        return;

    Vector<CSSPropertyID> nativeInvalidationProperties;
    Vector<AtomicString> customInvalidationProperties;

    if (!isUndefinedOrNull(inputPropertiesValue)) {
        Vector<String> properties = toImplArray<Vector<String>>(inputPropertiesValue, 0, isolate, exceptionState);

        if (exceptionState.hadException())
            return;

        for (const auto& property : properties) {
            CSSPropertyID propertyID = cssPropertyID(property);
            if (propertyID == CSSPropertyInvalid) {
                if (CSSVariableParser::isValidVariableName(property))
                    customInvalidationProperties.append(property);
            } else {
                // Disallow prefixes.
                if (property[0] == '-') {
                    addConsoleMessage(ConsoleMessage::create(JSMessageSource, WarningMessageLevel, property + " is a prefixed property which is not supported."));
                } else {
                    nativeInvalidationProperties.append(propertyID);
                }
            }
        }
    }

    v8::Local<v8::Value> prototypeValue;
    if (!v8Call(constructor->Get(context, v8String(isolate, "prototype")), prototypeValue))
        return;

    if (isUndefinedOrNull(prototypeValue)) {
        exceptionState.throwTypeError("The 'prototype' object on the class does not exist.");
        return;
    }

    if (!prototypeValue->IsObject()) {
        exceptionState.throwTypeError("The 'prototype' property on the class is not an object.");
        return;
    }

    v8::Local<v8::Object> prototype = v8::Local<v8::Object>::Cast(prototypeValue);

    v8::Local<v8::Value> paintValue;
    if (!v8Call(prototype->Get(context, v8String(isolate, "paint")), paintValue))
        return;

    if (isUndefinedOrNull(paintValue)) {
        exceptionState.throwTypeError("The 'paint' function on the prototype does not exist.");
        return;
    }

    if (!paintValue->IsFunction()) {
        exceptionState.throwTypeError("The 'paint' property on the prototype is not a function.");
        return;
    }

    v8::Local<v8::Function> paint = v8::Local<v8::Function>::Cast(paintValue);

    CSSPaintDefinition* definition = CSSPaintDefinition::create(scriptController()->getScriptState(), constructor, paint, nativeInvalidationProperties, customInvalidationProperties);
    m_paintDefinitions.set(name, definition);

    // Set the definition on any pending generators.
    GeneratorHashSet* set = m_pendingGenerators.get(name);
    if (set) {
        for (const auto& generator : *set) {
            if (generator) {
                generator->setDefinition(definition);
            }
        }
    }
    m_pendingGenerators.remove(name);
}

CSSPaintDefinition* PaintWorkletGlobalScope::findDefinition(const String& name)
{
    return m_paintDefinitions.get(name);
}

void PaintWorkletGlobalScope::addPendingGenerator(const String& name, CSSPaintImageGeneratorImpl* generator)
{
    Member<GeneratorHashSet>& set = m_pendingGenerators.add(name, nullptr).storedValue->value;
    if (!set)
        set = new GeneratorHashSet;
    set->add(generator);
}

DEFINE_TRACE(PaintWorkletGlobalScope)
{
    visitor->trace(m_paintDefinitions);
    visitor->trace(m_pendingGenerators);
    MainThreadWorkletGlobalScope::trace(visitor);
}

} // namespace blink
