/*
 * Copyright (C) 2004-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. ``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
 * 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 "DOMHTMLInputElementInternal.h"

#import "DOMFileListInternal.h"
#import "DOMHTMLElementInternal.h"
#import "DOMHTMLFormElementInternal.h"
#import "DOMNodeInternal.h"
#import "DOMNodeListInternal.h"
#import "DOMInternal.h"
#import "DOMPrivate.h"
#import "ExceptionHandlers.h"
#import <WebCore/ContainerNodeInlines.h>
#import <WebCore/ElementInlines.h>

#if TARGET_OS_IPHONE
#if __has_include(<UIKit/UITextAutofillSuggestion.h>)

#import <UIKit/UITextAutofillSuggestion.h>

#else

@interface UITextSuggestion : NSObject
@end

@interface UITextAutofillSuggestion : UITextSuggestion
@property (nonatomic, assign) NSString *username;
@property (nonatomic, assign) NSString *password;
@end

#endif // __has_include(<UIKit/UITextAutofillSuggestion.h>)
#endif // TARGET_OS_IPHONE

#import <WebCore/AutofillElements.h>
#import <WebCore/FileList.h>
#import <WebCore/HTMLElement.h>
#import <WebCore/HTMLFormElement.h>
#import <WebCore/HTMLInputElement.h>
#import <WebCore/HTMLNames.h>
#import <WebCore/HitTestResult.h>
#import <WebCore/JSExecState.h>
#import <WebCore/NodeList.h>
#import <WebCore/RenderElement.h>
#import <WebCore/ThreadCheck.h>
#import <WebCore/WebScriptObjectPrivate.h>
#import <wtf/GetPtr.h>
#import <wtf/URL.h>

#define IMPL static_cast<WebCore::HTMLInputElement*>(reinterpret_cast<WebCore::Node*>(_internal))

@implementation DOMHTMLInputElement

- (NSString *)accept
{
    WebCore::JSMainThreadNullState state;
    return IMPL->getAttribute(WebCore::HTMLNames::acceptAttr).createNSString().autorelease();
}

- (void)setAccept:(NSString *)newAccept
{
    WebCore::JSMainThreadNullState state;
    IMPL->setAttributeWithoutSynchronization(WebCore::HTMLNames::acceptAttr, newAccept);
}

- (NSString *)alt
{
    WebCore::JSMainThreadNullState state;
    return IMPL->getAttribute(WebCore::HTMLNames::altAttr).createNSString().autorelease();
}

- (void)setAlt:(NSString *)newAlt
{
    WebCore::JSMainThreadNullState state;
    IMPL->setAttributeWithoutSynchronization(WebCore::HTMLNames::altAttr, newAlt);
}

- (NSString *)autocomplete
{
    WebCore::JSMainThreadNullState state;
    return IMPL->autocomplete().createNSString().autorelease();
}

- (void)setAutocomplete:(NSString *)newAutocomplete
{
    WebCore::JSMainThreadNullState state;
    IMPL->setAttributeWithoutSynchronization(WebCore::HTMLNames::autocompleteAttr, newAutocomplete);
}

- (BOOL)autofocus
{
    WebCore::JSMainThreadNullState state;
    return IMPL->hasAttributeWithoutSynchronization(WebCore::HTMLNames::autofocusAttr);
}

- (void)setAutofocus:(BOOL)newAutofocus
{
    WebCore::JSMainThreadNullState state;
    IMPL->setBooleanAttribute(WebCore::HTMLNames::autofocusAttr, newAutofocus);
}

- (BOOL)defaultChecked
{
    WebCore::JSMainThreadNullState state;
    return IMPL->hasAttributeWithoutSynchronization(WebCore::HTMLNames::checkedAttr);
}

- (void)setDefaultChecked:(BOOL)newDefaultChecked
{
    WebCore::JSMainThreadNullState state;
    IMPL->setBooleanAttribute(WebCore::HTMLNames::checkedAttr, newDefaultChecked);
}

- (BOOL)checked
{
    WebCore::JSMainThreadNullState state;
    return IMPL->checked();
}

- (void)setChecked:(BOOL)newChecked
{
    WebCore::JSMainThreadNullState state;
    IMPL->setChecked(newChecked);
}

- (NSString *)dirName
{
    WebCore::JSMainThreadNullState state;
    return IMPL->getAttribute(WebCore::HTMLNames::dirnameAttr).createNSString().autorelease();
}

- (void)setDirName:(NSString *)newDirName
{
    WebCore::JSMainThreadNullState state;
    IMPL->setAttributeWithoutSynchronization(WebCore::HTMLNames::dirnameAttr, newDirName);
}

- (BOOL)disabled
{
    WebCore::JSMainThreadNullState state;
    return IMPL->hasAttributeWithoutSynchronization(WebCore::HTMLNames::disabledAttr);
}

- (void)setDisabled:(BOOL)newDisabled
{
    WebCore::JSMainThreadNullState state;
    IMPL->setBooleanAttribute(WebCore::HTMLNames::disabledAttr, newDisabled);
}

- (DOMHTMLFormElement *)form
{
    WebCore::JSMainThreadNullState state;
    return kit(WTF::getPtr(IMPL->form()));
}

- (DOMFileList *)files
{
    WebCore::JSMainThreadNullState state;
    return kit(WTF::getPtr(IMPL->files()));
}

- (void)setFiles:(DOMFileList *)newFiles
{
    WebCore::JSMainThreadNullState state;
    ASSERT(newFiles);

    IMPL->setFiles(core(newFiles));
}

- (NSString *)formAction
{
    WebCore::JSMainThreadNullState state;
    return IMPL->formAction().createNSString().autorelease();
}

- (void)setFormAction:(NSString *)newFormAction
{
    WebCore::JSMainThreadNullState state;
    IMPL->setAttributeWithoutSynchronization(WebCore::HTMLNames::formactionAttr, newFormAction);
}

- (NSString *)formEnctype
{
    WebCore::JSMainThreadNullState state;
    return IMPL->formEnctype().createNSString().autorelease();
}

- (void)setFormEnctype:(NSString *)newFormEnctype
{
    WebCore::JSMainThreadNullState state;
    IMPL->setAttributeWithoutSynchronization(WebCore::HTMLNames::formenctypeAttr, newFormEnctype);
}

- (NSString *)formMethod
{
    WebCore::JSMainThreadNullState state;
    return IMPL->formMethod().createNSString().autorelease();
}

- (void)setFormMethod:(NSString *)newFormMethod
{
    WebCore::JSMainThreadNullState state;
    IMPL->setAttributeWithoutSynchronization(WebCore::HTMLNames::formmethodAttr, newFormMethod);
}

- (BOOL)formNoValidate
{
    WebCore::JSMainThreadNullState state;
    return IMPL->hasAttributeWithoutSynchronization(WebCore::HTMLNames::formnovalidateAttr);
}

- (void)setFormNoValidate:(BOOL)newFormNoValidate
{
    WebCore::JSMainThreadNullState state;
    IMPL->setBooleanAttribute(WebCore::HTMLNames::formnovalidateAttr, newFormNoValidate);
}

- (NSString *)formTarget
{
    WebCore::JSMainThreadNullState state;
    return IMPL->getAttribute(WebCore::HTMLNames::formtargetAttr).createNSString().autorelease();
}

- (void)setFormTarget:(NSString *)newFormTarget
{
    WebCore::JSMainThreadNullState state;
    IMPL->setAttributeWithoutSynchronization(WebCore::HTMLNames::formtargetAttr, newFormTarget);
}

- (unsigned)height
{
    WebCore::JSMainThreadNullState state;
    return IMPL->height();
}

- (void)setHeight:(unsigned)newHeight
{
    WebCore::JSMainThreadNullState state;
    IMPL->setUnsignedIntegralAttribute(WebCore::HTMLNames::heightAttr, newHeight);
}

- (BOOL)indeterminate
{
    WebCore::JSMainThreadNullState state;
    return IMPL->indeterminate();
}

- (void)setIndeterminate:(BOOL)newIndeterminate
{
    WebCore::JSMainThreadNullState state;
    IMPL->setIndeterminate(newIndeterminate);
}

- (DOMHTMLElement *)list
{
    WebCore::JSMainThreadNullState state;
    return kit(WTF::getPtr(IMPL->list()));
}

- (NSString *)max
{
    WebCore::JSMainThreadNullState state;
    return IMPL->attributeWithoutSynchronization(WebCore::HTMLNames::maxAttr).createNSString().autorelease();
}

- (void)setMax:(NSString *)newMax
{
    WebCore::JSMainThreadNullState state;
    IMPL->setAttributeWithoutSynchronization(WebCore::HTMLNames::maxAttr, newMax);
}

- (int)maxLength
{
    WebCore::JSMainThreadNullState state;
    return IMPL->maxLength();
}

- (void)setMaxLength:(int)newMaxLength
{
    WebCore::JSMainThreadNullState state;
    raiseOnDOMError(IMPL->setMaxLength(newMaxLength));
}

- (NSString *)min
{
    WebCore::JSMainThreadNullState state;
    return IMPL->attributeWithoutSynchronization(WebCore::HTMLNames::minAttr).createNSString().autorelease();
}

- (void)setMin:(NSString *)newMin
{
    WebCore::JSMainThreadNullState state;
    IMPL->setAttributeWithoutSynchronization(WebCore::HTMLNames::minAttr, newMin);
}

- (BOOL)multiple
{
    WebCore::JSMainThreadNullState state;
    return IMPL->hasAttributeWithoutSynchronization(WebCore::HTMLNames::multipleAttr);
}

- (void)setMultiple:(BOOL)newMultiple
{
    WebCore::JSMainThreadNullState state;
    IMPL->setBooleanAttribute(WebCore::HTMLNames::multipleAttr, newMultiple);
}

- (NSString *)name
{
    WebCore::JSMainThreadNullState state;
    return IMPL->getNameAttribute().createNSString().autorelease();
}

- (void)setName:(NSString *)newName
{
    WebCore::JSMainThreadNullState state;
    IMPL->setAttributeWithoutSynchronization(WebCore::HTMLNames::nameAttr, newName);
}

- (NSString *)pattern
{
    WebCore::JSMainThreadNullState state;
    return IMPL->attributeWithoutSynchronization(WebCore::HTMLNames::patternAttr).createNSString().autorelease();
}

- (void)setPattern:(NSString *)newPattern
{
    WebCore::JSMainThreadNullState state;
    IMPL->setAttributeWithoutSynchronization(WebCore::HTMLNames::patternAttr, newPattern);
}

- (NSString *)placeholder
{
    WebCore::JSMainThreadNullState state;
    return IMPL->attributeWithoutSynchronization(WebCore::HTMLNames::placeholderAttr).createNSString().autorelease();
}

- (void)setPlaceholder:(NSString *)newPlaceholder
{
    WebCore::JSMainThreadNullState state;
    IMPL->setAttributeWithoutSynchronization(WebCore::HTMLNames::placeholderAttr, newPlaceholder);
}

- (BOOL)readOnly
{
    WebCore::JSMainThreadNullState state;
    return IMPL->hasAttributeWithoutSynchronization(WebCore::HTMLNames::readonlyAttr);
}

- (void)setReadOnly:(BOOL)newReadOnly
{
    WebCore::JSMainThreadNullState state;
    IMPL->setBooleanAttribute(WebCore::HTMLNames::readonlyAttr, newReadOnly);
}

- (BOOL)required
{
    WebCore::JSMainThreadNullState state;
    return IMPL->hasAttributeWithoutSynchronization(WebCore::HTMLNames::requiredAttr);
}

- (void)setRequired:(BOOL)newRequired
{
    WebCore::JSMainThreadNullState state;
    IMPL->setBooleanAttribute(WebCore::HTMLNames::requiredAttr, newRequired);
}

- (NSString *)size
{
    WebCore::JSMainThreadNullState state;
    return WTF::String::number(IMPL->size()).createNSString().autorelease();
}

- (void)setSize:(NSString *)newSize
{
    WebCore::JSMainThreadNullState state;
    IMPL->setSize(newSize.intValue);
}

- (NSString *)src
{
    WebCore::JSMainThreadNullState state;
    return IMPL->getURLAttribute(WebCore::HTMLNames::srcAttr).string().createNSString().autorelease();
}

- (void)setSrc:(NSString *)newSrc
{
    WebCore::JSMainThreadNullState state;
    IMPL->setAttributeWithoutSynchronization(WebCore::HTMLNames::srcAttr, newSrc);
}

- (NSString *)step
{
    WebCore::JSMainThreadNullState state;
    return IMPL->attributeWithoutSynchronization(WebCore::HTMLNames::stepAttr).createNSString().autorelease();
}

- (void)setStep:(NSString *)newStep
{
    WebCore::JSMainThreadNullState state;
    IMPL->setAttributeWithoutSynchronization(WebCore::HTMLNames::stepAttr, newStep);
}

- (NSString *)type
{
    WebCore::JSMainThreadNullState state;
    return IMPL->type().createNSString().autorelease();
}

- (void)setType:(NSString *)newType
{
    WebCore::JSMainThreadNullState state;
    IMPL->setAttributeWithoutSynchronization(WebCore::HTMLNames::typeAttr, newType);
}

- (NSString *)defaultValue
{
    WebCore::JSMainThreadNullState state;
    return IMPL->attributeWithoutSynchronization(WebCore::HTMLNames::valueAttr).createNSString().autorelease();
}

- (void)setDefaultValue:(NSString *)newDefaultValue
{
    WebCore::JSMainThreadNullState state;
    IMPL->setAttributeWithoutSynchronization(WebCore::HTMLNames::valueAttr, newDefaultValue);
}

- (NSString *)value
{
    WebCore::JSMainThreadNullState state;
    return IMPL->value()->createNSString().autorelease();
}

- (void)setValue:(NSString *)newValue
{
    WebCore::JSMainThreadNullState state;
    IMPL->setValue(newValue);
}

- (NSTimeInterval)valueAsDate
{
    WebCore::JSMainThreadNullState state;
    return kit(IMPL->valueAsDate());
}

- (void)setValueAsDate:(NSTimeInterval)newValueAsDate
{
    WebCore::JSMainThreadNullState state;
    raiseOnDOMError(IMPL->setValueAsDate(core(newValueAsDate)));
}

- (double)valueAsNumber
{
    WebCore::JSMainThreadNullState state;
    return IMPL->valueAsNumber();
}

- (void)setValueAsNumber:(double)newValueAsNumber
{
    WebCore::JSMainThreadNullState state;
    raiseOnDOMError(IMPL->setValueAsNumber(newValueAsNumber));
}

- (unsigned)width
{
    WebCore::JSMainThreadNullState state;
    return IMPL->width();
}

- (void)setWidth:(unsigned)newWidth
{
    WebCore::JSMainThreadNullState state;
    IMPL->setUnsignedIntegralAttribute(WebCore::HTMLNames::widthAttr, newWidth);
}

- (BOOL)willValidate
{
    WebCore::JSMainThreadNullState state;
    return IMPL->willValidate();
}

- (NSString *)validationMessage
{
    WebCore::JSMainThreadNullState state;
    return IMPL->validationMessage().createNSString().autorelease();
}

- (DOMNodeList *)labels
{
    WebCore::JSMainThreadNullState state;
    return kit(WTF::getPtr(IMPL->labels()));
}

- (int)selectionStart
{
    WebCore::JSMainThreadNullState state;
    return IMPL->selectionStart();
}

- (void)setSelectionStart:(int)newSelectionStart
{
    WebCore::JSMainThreadNullState state;
    IMPL->setSelectionStart(newSelectionStart);
}

- (int)selectionEnd
{
    WebCore::JSMainThreadNullState state;
    return IMPL->selectionEnd();
}

- (void)setSelectionEnd:(int)newSelectionEnd
{
    WebCore::JSMainThreadNullState state;
    IMPL->setSelectionEnd(newSelectionEnd);
}

- (NSString *)selectionDirection
{
    WebCore::JSMainThreadNullState state;
    return IMPL->selectionDirection().createNSString().autorelease();
}

- (void)setSelectionDirection:(NSString *)newSelectionDirection
{
    WebCore::JSMainThreadNullState state;
    IMPL->setSelectionDirection(newSelectionDirection);
}

- (NSString *)align
{
    WebCore::JSMainThreadNullState state;
    return IMPL->getAttribute(WebCore::HTMLNames::alignAttr).createNSString().autorelease();
}

- (void)setAlign:(NSString *)newAlign
{
    WebCore::JSMainThreadNullState state;
    IMPL->setAttributeWithoutSynchronization(WebCore::HTMLNames::alignAttr, newAlign);
}

- (NSString *)useMap
{
    WebCore::JSMainThreadNullState state;
    return IMPL->getAttribute(WebCore::HTMLNames::usemapAttr).createNSString().autorelease();
}

- (void)setUseMap:(NSString *)newUseMap
{
    WebCore::JSMainThreadNullState state;
    IMPL->setAttributeWithoutSynchronization(WebCore::HTMLNames::usemapAttr, newUseMap);
}

- (BOOL)incremental
{
    return NO;
}

- (void)setIncremental:(BOOL)newIncremental
{
}

- (NSString *)accessKey
{
    WebCore::JSMainThreadNullState state;
    return IMPL->getAttribute(WebCore::HTMLNames::accesskeyAttr).createNSString().autorelease();
}

- (void)setAccessKey:(NSString *)newAccessKey
{
    WebCore::JSMainThreadNullState state;
    IMPL->setAttributeWithoutSynchronization(WebCore::HTMLNames::accesskeyAttr, newAccessKey);
}

- (NSString *)altDisplayString
{
    WebCore::JSMainThreadNullState state;
    return WebCore::displayString(IMPL->attributeWithoutSynchronization(WebCore::HTMLNames::altAttr), core(self)).createNSString().autorelease();
}

- (NSURL *)absoluteImageURL
{
    WebCore::JSMainThreadNullState state;
    if (!IMPL->renderer() || !IMPL->renderer()->isImage())
        return nil;
    return [self _getURLAttribute:@"src"];
}

#if ENABLE(MEDIA_CAPTURE)
- (BOOL)capture
{
    WebCore::JSMainThreadNullState state;
    return IMPL->hasAttributeWithoutSynchronization(WebCore::HTMLNames::captureAttr);
}

- (void)setCapture:(BOOL)newCapture
{
    WebCore::JSMainThreadNullState state;
    IMPL->setBooleanAttribute(WebCore::HTMLNames::captureAttr, newCapture);
}
#endif

- (void)stepUp:(int)n
{
    WebCore::JSMainThreadNullState state;
    raiseOnDOMError(IMPL->stepUp(n));
}

- (void)stepDown:(int)n
{
    WebCore::JSMainThreadNullState state;
    raiseOnDOMError(IMPL->stepDown(n));
}

- (BOOL)checkValidity
{
    WebCore::JSMainThreadNullState state;
    return IMPL->checkValidity();
}

- (void)setCustomValidity:(NSString *)error
{
    WebCore::JSMainThreadNullState state;
    IMPL->setCustomValidity(error);
}

- (void)select
{
    WebCore::JSMainThreadNullState state;
    IMPL->select();
}

- (void)setRangeText:(NSString *)replacement
{
    WebCore::JSMainThreadNullState state;
    raiseOnDOMError(IMPL->setRangeText(String { replacement }));
}

- (void)setRangeText:(NSString *)replacement start:(unsigned)start end:(unsigned)end selectionMode:(NSString *)selectionMode
{
    WebCore::JSMainThreadNullState state;
    raiseOnDOMError(IMPL->setRangeText(String { replacement }, start, end, selectionMode));
}

- (void)setSelectionRange:(int)start end:(int)end
{
    WebCore::JSMainThreadNullState state;
    IMPL->setSelectionRange(start, end);
}

- (void)click
{
    WebCore::JSMainThreadNullState state;
    IMPL->click();
}

- (void)setValueForUser:(NSString *)inValue
{
    WebCore::JSMainThreadNullState state;
    IMPL->setValueForUser(inValue);
}

- (NSDictionary *)_autofillContext
{
    WebCore::JSMainThreadNullState state;
    if (!WebCore::AutofillElements::computeAutofillElements(*IMPL))
        return nil;

    NSURL *documentURL = [NSURL URLWithString:self.ownerDocument.URL];
    if (!documentURL)
        return nil;

    return @{ @"_WebViewURL" : documentURL };
}

#if TARGET_OS_IPHONE
- (void)insertTextSuggestion:(UITextAutofillSuggestion *)credentialSuggestion
{
    WebCore::JSMainThreadNullState state;
    if (is<WebCore::HTMLInputElement>(IMPL)) {
        if (auto autofillElements = WebCore::AutofillElements::computeAutofillElements(*IMPL))
            autofillElements->autofill(credentialSuggestion.username, credentialSuggestion.password);
    }
}
#endif // TARGET_OS_IPHONE

- (BOOL)canShowPlaceholder
{
    WebCore::JSMainThreadNullState state;
    return IMPL->canShowPlaceholder();
}

- (void)setCanShowPlaceholder:(BOOL)canShowPlaceholder
{
    WebCore::JSMainThreadNullState state;
    IMPL->setCanShowPlaceholder(canShowPlaceholder);
}

@end

WebCore::HTMLInputElement* core(DOMHTMLInputElement *wrapper)
{
    return wrapper ? reinterpret_cast<WebCore::HTMLInputElement*>(wrapper->_internal) : 0;
}

DOMHTMLInputElement *kit(WebCore::HTMLInputElement* value)
{
    WebCoreThreadViolationCheckRoundOne();
    return static_cast<DOMHTMLInputElement*>(kit(static_cast<WebCore::Node*>(value)));
}

#undef IMPL
