/*
 * Copyright (C) 2010 Google Inc. All rights reserved.
 * Copyright (C) 2011 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:
 *
 *     * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *     * 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.
 *     * Neither the name of Google Inc. nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT
 * OWNER 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.
 */

#include "third_party/blink/renderer/core/html/forms/password_input_type.h"

#include "base/memory/scoped_refptr.h"
#include "third_party/blink/renderer/core/dom/document.h"
#include "third_party/blink/renderer/core/dom/dom_token_list.h"
#include "third_party/blink/renderer/core/dom/node_computed_style.h"
#include "third_party/blink/renderer/core/editing/frame_selection.h"
#include "third_party/blink/renderer/core/events/keyboard_event.h"
#include "third_party/blink/renderer/core/frame/local_frame.h"
#include "third_party/blink/renderer/core/frame/web_feature.h"
#include "third_party/blink/renderer/core/geometry/dom_rect.h"
#include "third_party/blink/renderer/core/html/forms/form_controller.h"
#include "third_party/blink/renderer/core/html/forms/html_input_element.h"
#include "third_party/blink/renderer/core/html/shadow/shadow_element_names.h"
#include "third_party/blink/renderer/core/input/keyboard_event_manager.h"
#include "third_party/blink/renderer/core/input_type_names.h"
#include "third_party/blink/renderer/core/layout/layout_text_control_single_line.h"
#include "third_party/blink/renderer/platform/wtf/assertions.h"

namespace blink {

void PasswordInputType::CountUsage() {
  CountUsageIfVisible(WebFeature::kInputTypePassword);
  if (GetElement().FastHasAttribute(html_names::kMaxlengthAttr))
    CountUsageIfVisible(WebFeature::kInputTypePasswordMaxLength);
}

const AtomicString& PasswordInputType::FormControlType() const {
  return input_type_names::kPassword;
}

bool PasswordInputType::ShouldSaveAndRestoreFormControlState() const {
  return false;
}

FormControlState PasswordInputType::SaveFormControlState() const {
  // Should never save/restore password fields.
  NOTREACHED();
  return FormControlState();
}

void PasswordInputType::RestoreFormControlState(const FormControlState&) {
  // Should never save/restore password fields.
  NOTREACHED();
}

bool PasswordInputType::ShouldRespectListAttribute() {
  return false;
}

bool PasswordInputType::NeedsContainer() const {
  return RuntimeEnabledFeatures::PasswordRevealEnabled();
}

void PasswordInputType::CreateShadowSubtree() {
  BaseTextInputType::CreateShadowSubtree();

  if (RuntimeEnabledFeatures::PasswordRevealEnabled()) {
    Element* container = ContainerElement();
    Element* view_port = GetElement().UserAgentShadowRoot()->getElementById(
        shadow_element_names::kIdEditingViewPort);
    DCHECK(container);
    DCHECK(view_port);
    container->InsertBefore(MakeGarbageCollected<PasswordRevealButtonElement>(
                                GetElement().GetDocument()),
                            view_port->nextSibling());
  }
}

void PasswordInputType::DidSetValueByUserEdit() {
  if (RuntimeEnabledFeatures::PasswordRevealEnabled()) {
    // If the last character is deleted, we hide the reveal button.
    if (GetElement().value().IsEmpty()) {
      should_show_reveal_button_ = false;
    }
    UpdatePasswordRevealButton();
  }
  BaseTextInputType::DidSetValueByUserEdit();
}

void PasswordInputType::DidSetValue(const String& string, bool value_changed) {
  if (RuntimeEnabledFeatures::PasswordRevealEnabled()) {
    if (value_changed) {
      // Hide the password if the value is changed by script.
      should_show_reveal_button_ = false;
      UpdatePasswordRevealButton();
    }
  }
  BaseTextInputType::DidSetValue(string, value_changed);
}

void PasswordInputType::UpdateView() {
  BaseTextInputType::UpdateView();

  if (RuntimeEnabledFeatures::PasswordRevealEnabled())
    UpdatePasswordRevealButton();
}

void PasswordInputType::CapsLockStateMayHaveChanged() {
  auto& document = GetElement().GetDocument();
  LocalFrame* frame = document.GetFrame();
  // Only draw the caps lock indicator if these things are true:
  // 1) The field is a password field
  // 2) The frame is active
  // 3) The element is focused
  // 4) The caps lock is on
  const bool should_draw_caps_lock_indicator =
      frame && frame->Selection().FrameIsFocusedAndActive() &&
      document.FocusedElement() == GetElement() &&
      KeyboardEventManager::CurrentCapsLockState();

  if (should_draw_caps_lock_indicator != should_draw_caps_lock_indicator_) {
    should_draw_caps_lock_indicator_ = should_draw_caps_lock_indicator;
    if (auto* layout_object = GetElement().GetLayoutObject())
      layout_object->SetShouldDoFullPaintInvalidation();
  }
}

bool PasswordInputType::ShouldDrawCapsLockIndicator() const {
  return should_draw_caps_lock_indicator_;
}

void PasswordInputType::UpdatePasswordRevealButton() {
  Element* button = GetElement().UserAgentShadowRoot()->getElementById(
      shadow_element_names::kIdPasswordRevealButton);

  // Update the glyph.
  const AtomicString reveal("reveal");
  if (GetElement().ShouldRevealPassword())
    button->classList().Add(reveal);
  else
    button->classList().Remove(reveal);

  // Update the visibility.
  if (should_show_reveal_button_) {
    // Show the reveal button only when the width is enough for the reveal
    // button plus a few characters. (The number of characters slightly varies
    // based on the font size/family).
    const float kRevealButtonWidthEm = 1.3;  // 1.3em
    const float kPasswordMinWidthEm =
        0.7;                       // 0.7em which is enough for ~2 chars.
    const int kLeftMarginPx = 3;   // 3px
    const int kRightMarginPx = 3;  // 3px
    float current_width = GetElement().getBoundingClientRect()->width();
    float width_needed = GetElement().ComputedStyleRef().FontSize() *
                             (kRevealButtonWidthEm + kPasswordMinWidthEm) +
                         kLeftMarginPx + kRightMarginPx;

    if (current_width >= width_needed) {
      button->RemoveInlineStyleProperty(CSSPropertyID::kDisplay);
    }
  } else {
    button->SetInlineStyleProperty(CSSPropertyID::kDisplay, CSSValueID::kNone);
    // Always obscure password when the reveal button is hidden.
    // (ex. out of focus)
    GetElement().SetShouldRevealPassword(false);
  }
}

void PasswordInputType::ForwardEvent(Event& event) {
  BaseTextInputType::ForwardEvent(event);

  if (GetElement().GetLayoutObject() &&
      !GetElement().GetForceReattachLayoutTree() &&
      (event.type() == event_type_names::kBlur ||
       event.type() == event_type_names::kFocus))
    CapsLockStateMayHaveChanged();
}

void PasswordInputType::HandleBlurEvent() {
  if (RuntimeEnabledFeatures::PasswordRevealEnabled()) {
    should_show_reveal_button_ = false;
    UpdatePasswordRevealButton();
  }

  BaseTextInputType::HandleBlurEvent();
}

void PasswordInputType::HandleBeforeTextInsertedEvent(
    BeforeTextInsertedEvent& event) {
  if (RuntimeEnabledFeatures::PasswordRevealEnabled()) {
    // This is the only scenario we go from no reveal button to showing the
    // reveal button: the password is empty and we have some user input.
    if (GetElement().value().IsEmpty())
      should_show_reveal_button_ = true;
  }

  TextFieldInputType::HandleBeforeTextInsertedEvent(event);
}

void PasswordInputType::HandleKeydownEvent(KeyboardEvent& event) {
  if (RuntimeEnabledFeatures::PasswordRevealEnabled()) {
    if (should_show_reveal_button_) {
      // Alt-F8 to reveal/obscure password
      if (event.getModifierState("Alt") && event.key() == "F8") {
        GetElement().SetShouldRevealPassword(
            !GetElement().ShouldRevealPassword());
        UpdatePasswordRevealButton();
        event.SetDefaultHandled();
      }
    }
  }

  if (!event.DefaultHandled())
    BaseTextInputType::HandleKeydownEvent(event);
}

bool PasswordInputType::SupportsInputModeAttribute() const {
  return true;
}

}  // namespace blink
