/**---------------------------------------------------------------------------
* 版权 2004 啄木鸟基金会
* 保留一切权利。
* 
* 重新分发或者使用源代码格式和二进制格式，无论是否修改，必须在符合
* 以下许可条件的情况下进行：
* 1. 重新分发的源代码必须保留上述版权信息、本许可条件列表以及下列
*    否认声明。
* 2. 重新分发的二进制格式程序必须再次产生上述版权信息，本许可条件列
*    表以及在本分发中的文档或者其他材料中提供的否认声明。
*
* 本软件是由作者和参与者“照此”提供，并且任何显式或隐式的保证，只
* 包含在内但不被其限制，否认任何商业性和特殊目的适切性的隐式担保
* 之效力。本软件的作者或参与者不对由于本软件造成的任何直接地、
* 间接地、连带地、特殊地、惩戒性地，或者由此而产生地损害（还包括
* 以下的不被其限制的内容在内：替代品或服务地取得；使用过程、数据、
* 或由此产生的收益之损失；或商业行为的中断）发生在即使被告知可能
* 出现上述损害后，仍设法摆脱使用本软件的过程中，无论其起因和任何
* 责任地推测，其是否属于合同范畴、限定的义务、或者民事侵权行为
*（包括疏忽及其他）都否认其责任。
* 
* 
*
* Copyright (c) 2004 The Woodpecker Foundation
* 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 AUTHOR 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 AUTHOR 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 <stdio.h>
#include <glib.h>
#include <assert.h>
#include "simpleshm.h"

#define MAXROW 10

SSPool *SScreatePool(int size)
{
    SSPool *pool;

    pool = (SSPool *)malloc(sizeof(SSPool));
    pool->ghtContainer = g_hash_table_new(NULL, NULL);
    pool->maxSize = size;
    pool->size = 0;
    pool->list = NULL;

    //TODO :attach to share memory
}

int SSdestroyPool(SSPool *pool)
{
    //TODO: free the malloc object
    g_list_free(pool->list);
    g_hash_table_destroy(pool->ghtContainer);
}

int SSgetSize(SSPool *pool)
{
    return pool->size;
}

int SSpush(SSPool *pool, gpointer key, gpointer value)
{
    assert(pool != NULL);
    g_hash_table_insert(pool->ghtContainer, key, value);

    pool->list = g_list_prepend(pool->list, key);
    pool->size =+ 1;
}

gpointer SSpull(SSPool *pool)
{
    gpointer *ptr;

    assert(pool != NULL);
    if (pool->size <= 0) 
        return NULL;

    ptr = g_list_nth_data(pool->list, 0);
    g_list_delete_link(pool->list, g_list_nth(pool->list, 0));
    pool->size =- 1;

    return ptr;
}

gpointer SSpopup(SSPool *pool)
{
    gpointer ptr;

    assert(pool != NULL);
    if (pool->size <= 0) 
        return NULL;

    ptr = g_list_nth_data(pool->list, pool->size - 1);
    g_list_delete_link(pool->list, g_list_nth(pool->list, pool->size - 1));
    pool->size =- 1;

    return ptr;
}

/** 
 * test suit for:
 *                SSCreatePool
 *                SSDestoryePool
 *                SSgetSize
 *                SSpush
 *                SSpopup
 * 
 */
int testSSPool()
{
    int i;
    char key[10], value[100];
    SSPool *pool;
    
    pool = SScreatePool(0);

    /* push message into pool */
    for (i = 0; i < MAXROW; i ++){
        sprintf(key, "%d", i);
        sprintf(value, "%s", "中文value%d", i);
        SSpush(pool, (gpointer)key, (gpointer)value);
    }
    printf("now push %d row into pool.\n hash table size is:", i, SSgetSize(pool));

    /* popup message from pool */
    for (i = 0; i < MAXROW; i++){
        strcpy(value, (char *)SSpopup(pool));
        printf("(%s, %s) read\n", key, value);
    }
    printf("now popup %d row from pool.\n hash table size is:", i, SSgetSize(pool));
    
    return ;
}
int testGlib()
{
    int i;
    char s[100], key[10];
    GHashTable *gt;

    gt = g_hash_table_new(NULL, NULL);
    
    for (i = 0; i < MAXROW; i ++){
    	sprintf(s, "中文啦long long ago there was a king who love horse very much, hello, 和咯 value%d", i);
        sprintf(key, "%d", i);
    	g_hash_table_insert(gt, (gpointer)key, (gpointer)s);
    }
    printf("%d rows inserted.\n", MAXROW);
    
    for (i = 0; i < MAXROW; i ++){
        sprintf(key, "%d", i);
        strcpy(s, (char *)g_hash_table_lookup(gt, (gpointer)key));
    	printf("read (%s, %s)\n", key, s);
    }
    strcpy(key, "2");
    strcpy(s, (char *)g_hash_table_lookup(gt, (gpointer)(key)));
    printf("example read (%s, %s)\n", key, s);
    printf("%d rows read.\n", MAXROW);

    g_hash_table_destroy(gt);
}

int testshm(char *s)
{
    int fd, shmid, i = 9;
    shmid = shmcreate("/tmp/hello123", 1000);
    printf("shmid=%d\n", shmid);
    if (strcmp(s, "w") == 0)
        shmwrite(shmid, &i, sizeof(int));
    else{
        i = 0;
        shmread(shmid, &i, sizeof(int));
        printf("read i = %d\n", i);
    }

}
int main(int argc, char *args[])
{
    testshm(args[1]);     
//  testGlib();
//  testSSPool();
}
