/*
 * Copyright 2008 The Yacafe Project. 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 THE YACAFE PROJECT ``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 YACAFE PROJECT 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.
 *
 * The views and conclusions contained in the software and documentation are
 * those of the authors and should not be interpreted as representing official
 * policies, either expressed or implied, of the Yacafe Project.
 */

#include <string.h>
#include "sample.h"

#define LOGIN_ERROR_PROPERTY_CREATE (0x01 << 0)
#define LOGIN_ERROR_PROPERTY_LOAD   (0x01 << 1)
#define LOGIN_ERROR_USERNAME        (0x01 << 2)
#define LOGIN_ERROR_PASSWORD        (0x01 << 3)
#define LOGIN_ERROR_SESSION_CREATE  (0x01 << 4)

#define LOGIN_MESSAGE_FAILURE           "Yacafe Sample Application にログインする事が出来ません"
#define LOGIN_MESSAGE_PREFIX            "<br/>\n　・"
#define LOGIN_MESSAGE_PROPERTY_CREATE   "システムエラーが発生しました"
#define LOGIN_MESSAGE_PROPERTY_LOAD     "定義ファイル " USER_PROPERTY_FILE " をロード出来ません"
#define LOGIN_MESSAGE_USERNAME_PASSWORD "ユーザー名またはパスワードが一致しません"
#define LOGIN_MESSAGE_SESSION_CREATE    "セッションの作成に失敗しました"

#define LOGIN_SUBMIT_NORMAL "%A5%ED%A5%B0%A5%A4%A5%F3"
#define LOGIN_SUBMIT_FORCED "%CC%B5%BB%EB"

static int
login_auth(const request_t *request);

char *
action(request_t *request, response_t *response, session_t *session)
{
	char *submit, *sessionid;
	int   err;
	request_item_t *item;
	xstring_t *message;

	submit = request_item_get_value(request_get_item_by_name(request, "submit"));

	if(strutil_isempty(submit))
	{
		goto VIEW;
	}

	err = login_auth(request);

	if(err)
	{
		goto ERROR;
	}

	sessionid = session_open(session, NULL);

	if(strutil_isempty(sessionid))
	{
		err = LOGIN_ERROR_SESSION_CREATE;

		goto ERROR;
	}

	item = request_get_item_by_name(request, "sessionid");

	if(!item)
	{
		item = request_append_item(request, "sessionid", NULL);
	}

	request_item_set_value(item, sessionid);

	return strutil_dup("success");

ERROR:
	message = xstring_create(LOGIN_MESSAGE_FAILURE);

	if(err & LOGIN_ERROR_PROPERTY_CREATE)
	{
		xstring_concat(message, LOGIN_MESSAGE_PROPERTY_CREATE, LOGIN_MESSAGE_PREFIX);
	}

	if(err & LOGIN_ERROR_PROPERTY_LOAD)
	{
		xstring_concat(message, LOGIN_MESSAGE_PROPERTY_LOAD, LOGIN_MESSAGE_PREFIX);
	}

	if(err & (LOGIN_ERROR_USERNAME | LOGIN_ERROR_PASSWORD))
	{
		xstring_concat(message, LOGIN_MESSAGE_USERNAME_PASSWORD, LOGIN_MESSAGE_PREFIX);

		response_node_append_property(response_append_node(response, "username"), "class", "error");
		response_node_append_property(response_append_node(response, "password"), "class", "error");
	}

	if(err & LOGIN_ERROR_SESSION_CREATE)
	{
		xstring_concat(message, LOGIN_MESSAGE_SESSION_CREATE, LOGIN_MESSAGE_PREFIX);
	}

	response_node_append_property(response_append_node(response, "message"), "text", xstring_raw(message));

	xstring_destroy(message);

VIEW:
	return strutil_dup("failure");
}

static int
login_auth(const request_t *request)
{
property_t *property;
int         err = 0;

	property = property_create();

	if(!property)
	{
		err = LOGIN_ERROR_PROPERTY_CREATE;

		goto ERROR;
	}

	err = property_load(property, USER_PROPERTY_FILE);

	if(err)
	{
		err = LOGIN_ERROR_PROPERTY_LOAD;

		goto ERROR;
	}

	if(!strutil_isequal(property_item_get_value(property_get_item_by_name(property, "USERNAME")), request_item_get_value(request_get_item_by_name(request, "username"))))
	{
		err = LOGIN_ERROR_USERNAME;

		goto ERROR;
	}

	if(!strutil_isequal(property_item_get_value(property_get_item_by_name(property, "PASSWORD")), request_item_get_value(request_get_item_by_name(request, "password"))))
	{
		err = LOGIN_ERROR_PASSWORD;

		goto ERROR;
	}

ERROR:
	property_destroy(property);

	return err;
}
