/*
 * Copyright (C) 2009 Google 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 "config.h"
#include "WebPasswordFormData.h"

#include "HTMLNames.h"
#include "core/dom/Document.h"
#include "core/html/HTMLFormElement.h"
#include "core/html/HTMLInputElement.h"
#include "weborigin/KURL.h"

#include "DOMUtilitiesPrivate.h"
#include "WebPasswordFormUtils.h"

using namespace WebCore;

namespace WebKit {

namespace {

// Helper to determine which password is the main one, and which is
// an old password (e.g on a "make new password" form), if any.
bool locateSpecificPasswords(PasswordFormFields* fields,
                             HTMLInputElement** password,
                             HTMLInputElement** oldPassword)
{
    ASSERT(fields);
    ASSERT(password);
    ASSERT(oldPassword);
    switch (fields->passwords.size()) {
    case 1:
        // Single password, easy.
        *password = fields->passwords[0];
        break;
    case 2:
        if (fields->passwords[0]->value() == fields->passwords[1]->value())
            // Treat two identical passwords as a single password.
            *password = fields->passwords[0];
        else {
            // Assume first is old password, second is new (no choice but to guess).
            *oldPassword = fields->passwords[0];
            *password = fields->passwords[1];
        }
        break;
    case 3:
        if (fields->passwords[0]->value() == fields->passwords[1]->value()
            && fields->passwords[0]->value() == fields->passwords[2]->value()) {
            // All three passwords the same? Just treat as one and hope.
            *password = fields->passwords[0];
        } else if (fields->passwords[0]->value() == fields->passwords[1]->value()) {
            // Two the same and one different -> old password is duplicated one.
            *oldPassword = fields->passwords[0];
            *password = fields->passwords[2];
        } else if (fields->passwords[1]->value() == fields->passwords[2]->value()) {
            *oldPassword = fields->passwords[0];
            *password = fields->passwords[1];
        } else {
            // Three different passwords, or first and last match with middle
            // different. No idea which is which, so no luck.
            return false;
        }
        break;
    default:
        return false;
    }
    return true;
}

// Helped method to clear url of unneeded parts.
KURL stripURL(const KURL& url)
{
    KURL strippedURL = url;
    strippedURL.setUser(String());
    strippedURL.setPass(String());
    strippedURL.setQuery(String());
    strippedURL.setFragmentIdentifier(String());
    return strippedURL;
}

// Helper to gather up the final form data and create a PasswordForm.
void assemblePasswordFormResult(const KURL& fullOrigin,
                                const KURL& fullAction,
                                HTMLFormControlElement* submit,
                                HTMLInputElement* userName,
                                const Vector<String>& alternateUserNames,
                                HTMLInputElement* oldPassword,
                                HTMLInputElement* password,
                                WebPasswordFormData* result)
{
    // We want to keep the path but strip any authentication data, as well as
    // query and ref portions of URL, for the form action and form origin.
    result->action = stripURL(fullAction);
    result->origin = stripURL(fullOrigin);

    // Naming is confusing here because we have both the HTML form origin URL
    // the page where the form was seen), and the "origin" components of the url
    // (scheme, host, and port).
    KURL signonRealmURL = stripURL(fullOrigin);
    signonRealmURL.setPath("");
    result->signonRealm = signonRealmURL;

    result->possibleUserNames = alternateUserNames;
    if (submit)
        result->submitElement = submit->name();
    if (userName) {
        result->userNameElement = userName->name();
        result->userNameValue = userName->value();
    }
    if (password) {
        result->passwordElement = password->name();
        result->passwordValue = password->value();
        result->passwordShouldAutocomplete = password->shouldAutocomplete();
    }
    if (oldPassword) {
        result->oldPasswordElement = oldPassword->name();
        result->oldPasswordValue = oldPassword->value();
    }
}

} // namespace

WebPasswordFormData::WebPasswordFormData(const WebFormElement& webForm)
{
    RefPtr<HTMLFormElement> form = webForm.operator PassRefPtr<HTMLFormElement>();
    PasswordFormFields fields;
    findPasswordFormFields(form.get(), &fields);

    // Get the document URL
    KURL fullOrigin(ParsedURLString, form->document().documentURI());

    // Calculate the canonical action URL
    String action = form->action();
    if (action.isNull())
        action = ""; // missing 'action' attribute implies current URL
    KURL fullAction = form->document().completeURL(action);
    if (!fullAction.isValid())
        return;

    // Determine the types of the password fields
    HTMLInputElement* password = 0;
    HTMLInputElement* oldPassword = 0;
    if (!locateSpecificPasswords(&fields, &password, &oldPassword))
        return;

    assemblePasswordFormResult(fullOrigin, fullAction,
                               fields.submit, fields.userName,
                               fields.alternateUserNames,
                               oldPassword, password, this);
}

} // namespace WebKit
