#include <stdio.h>
#include <stdlib.h>
#include <assert.h>

#include "list.h"

void list_init(List_t *list) {
    list->head = NULL;
    list->tail = NULL;
    list->len = 0;
}

bool list_is_empty(List_t *list) {
    return (list->head == NULL);
}

static struct List_Node_t *make_node(void *data)    //把用户传递过来的数据打包为一个链表节点
{
    struct List_Node_t *n;

    n = (struct List_Node_t *) malloc(sizeof(struct List_Node_t));
    assert(n != NULL);

    n->next = NULL;
    n->data = data;

    return n;
}

void list_insert_at_head(List_t *list, void *data)    //头插法
{
    struct List_Node_t *n;
    n = make_node(data);

    if (list->head == NULL) { //如果是空链表
        list->head = n;
        list->tail = n;
    } else {                   //如果不是非空链表
        n->next = list->head;
        list->head = n;
    }
    list->len++;
}

void list_insert_at_index(List_t *list, void *data, long index) //定插法
{
    long i = 1; //从1开始算
    struct List_Node_t *p, *n;

    p = list->head;

    while (p && i < index) {
        p = p->next;
        i++;
    }

    if (p) { //如果链表遍历完了，计数i还没到index，说明第index个节点不存在。
        n = make_node(data);
        n->next = p->next;
        p->next = n;
        list->len++;
    }
}

void list_insert_at_tail(List_t *list, void *data)    //尾插法
{
    struct List_Node_t *n;
    n = make_node(data);

    if (list_is_empty(list)) {    //如果是空链表
        list->head = n;
        list->tail = n;
    } else {                      //如果不是非空链表
        list->tail->next = n;
        list->tail = n;
    }
    list->len++;
}

//void list_insert(List_t *list, void *data)    //默认采用尾插法
//{
//#if 0
//    list_insert_at_tail(list, data);
//#else
//    struct List_Node_t *n;
//    n = make_node(data);
//    if(list->head == NULL){
//        list->head = n;
//        list->tail = n;
//    } else {
//        list->tail->next = n;
//        list->tail = n;
//    }
//    list->len++;
//#endif
//}


void list_insert(List_t *list, void *data) {
    struct List_Node_t *n;

    n = make_node(data);

    if (list->head == NULL) {
        list->head = n;
        list->tail = n;
    } else {
        list->tail->next = n;
        list->tail = n;
    }
    list->len++;
}

void *list_delete(List_t *list, void *key, int (*compare)(const void *, const void *)) {
    void *data;
    struct List_Node_t *n, *t;
    n = list->head;

    if (!compare(n->data, key)) {    //如果要删除的节点为首节点
        t = n;
        data = n->data;
        list->head = n->next;
        free(t);
        list->len--;
        return data;
    }

    while (n->next != NULL) {        //遍历查找符合条件的节点，删除之
        if (compare(n->next->data, key) == 0) {    //只删除第一个符合条件的节点。
            t = n->next;
            if (n->next == list->tail) {
                list->tail = n;
            }
            n->next = n->next->next;
            data = t->data;
            free(t);
            list->len--;
            return data;    //把删除的数据返回给用户，供用户后续的处理使用。
        }
        n = n->next;
    }
    return NULL;    //没找到匹配的节点，返回NULL
}

void *list_search(List_t *list, void *key, int (*compare)(const void *, const void *)) {
    struct List_Node_t *n;
    n = list->head;

    while (n) {
        if (!compare(n->data, key)) {    //找到了，返回找到的数据
            return n->data;
        }
        n = n->next;
    }

    return NULL;    //找不到，返回NULL
}

static struct List_Node_t *find_min_node(List_t *list,
                                  int (*compare)(const void *, const void *)) {
    struct List_Node_t *min, *n;

    n = list->head;
    min = list->head;

    while (n) {
        if (compare(min->data, n->data) > 0) {
            min = n;
        }
        n = n->next;
    }

    return min;
}

static void delete_node(List_t *list, struct List_Node_t *key) {
    struct List_Node_t *n;

    n = list->head;

    if (n == key) {
        list->head = n->next;
        return;
    }

    while (n->next) {
        if (n->next == key) {
            if (key == list->tail) {
                list->tail = n;
            }
            n->next = n->next->next;
            return;
        }
        n = n->next;
    }
}

static void insert_node(List_t *list, struct List_Node_t *key) {
    if (list->head == NULL) {
        list->head = key;
        list->tail = key;
    } else {
        list->tail->next = key;
        list->tail = key;
    }
}

void list_sort(List_t *list,
               int (*compare)(const void *, const void *)) {
    List_t tmp;
    struct List_Node_t *n;

    list_init(&tmp);

    while (!list_is_empty(list)) {
        n = find_min_node(list, compare);
        delete_node(list, n);
        n->next = NULL;
        insert_node(&tmp, n);
    }
    list->head = tmp.head;
    list->tail = tmp.tail;
}

void list_traverse(List_t *list, void (*handle)(void *)) {
    struct List_Node_t *p;
    p = list->head;

    while (p) {
        handle(p->data);
        p = p->next;
    }
}

void list_reverse(List_t *list) {
    struct List_Node_t *pre = NULL, *next, *p = list->head;

    list->tail = list->head;    //tail指向head；
    while (p) {
        next = p->next;
        if (!next) {  //当p->next为最后一个节点时，让head指向p->next
            list->head = p;
        }
        //记录当前节点为pre，作为下一个节点的next.第一个节点为NULL，初始化时已定义。
        p->next = pre;
        pre = p;
        p = next;
    }
}

long list_get_lenth(List_t *list) {
    return (list->len);
}

void *list_get_element(List_t *list, int idx) {
    int i = 1;
    struct List_Node_t *n;
    n = list->head;

    while (n && i < idx) {
        i++;
        n = n->next;
    }

    if (n) {
        return n->data;
    }

    return NULL;
}

void list_destroy(List_t *list, void (*destroy)(void *)) {
    list->len = 0;
    struct List_Node_t *n, *t;
    n = list->head;

    while (n) {
        t = n->next;    //t只起一个记录n->next的功能，否则后面把n free掉之后，就找不到n->next了。
        if (destroy) {  //传递用户自定义的数据处理函数，为0时不执行
            destroy(n->data);    //使用用户提供的destroy函数来释放用户传递过来的数据。
        }
        free(n);
        n = t;  //把n free掉之后，再把t给n，相当于把n->next给n,如此循环遍历链表，挨个删除，
    }
}