#include "list.h"
#include "stdlib.h"
#include "string.h"
#include "stdio.h"
#include "board.h"
#include "mystdlib.h"
#include "debug.h"
#include "bytearray.h"
#include "rtthread.h"

#define LIST_APPEND_SKIP  10


typedef struct{
  int32_t next;
  int32_t prev;
  uint32_t data[0];
}list_node_def;


struct _list_def{
  int32_t all;
  int32_t used;
  int32_t block_size;
  int32_t block_size4;
  rt_mutex_t mutex;
  int32_t head;
  int32_t tail;
  sub_fun_def sub;
  del_fun_def del;
  str_fun_def str;
  uint32_t data[0];
};

//#define list_enter_mutex(l)\
//      rt_mutex_take((l)->mutex,RT_WAITING_FOREVER)
//      
//#define list_exit_mutex(l)\
//      rt_mutex_release((l)->mutex)

#define list_enter_mutex(l)
#define list_exit_mutex(l)
#define rt_mutex_create(...) 0
#define rt_mutex_delete(l)

list_def *list_creat(int block_size,sub_fun_def sub,del_fun_def del,str_fun_def str)
{
  static uint16_t count=0;
	char s1[16]={0};
	sprintf(s1,"list_mut#%d",count);
  int size=0;
  int block_size4;
  list_def *l;
  size+=sizeof(list_def);
  // 4字节对齐
  block_size4=((block_size+3)/4)*4;
  size+=(sizeof(list_node_def)+block_size4)*LIST_APPEND_SKIP;
  l=malloc(size);
  param_check(l);
  l->all=LIST_APPEND_SKIP;
  l->used=0;
  l->block_size=block_size;
  l->block_size4=block_size4;
  l->mutex=rt_mutex_create(s1,RT_IPC_FLAG_FIFO);
  l->head=-1;
  l->tail=-1;
  l->sub=sub;
  l->del=del;
  l->str=str;
  
  // 初始化列表
  list_node_def *node;
  node=(list_node_def *)l->data;
  for(int i=0;i<l->all;i++)
  {
    node->next=-1;
    node->prev=-1;
    node=(list_node_def *)((uint32_t)node+sizeof(list_node_def)+l->block_size4);
  }
  count++;
  return l;
}


// 对于数据里有指针数据的成员,需要提供del函数
void _list_delete(list_def **l)
{
  param_check(l);
  param_check(*l);
  list_enter_mutex(*l);
  if((*l)->del)
  {
    for(int i=0;i<(*l)->used;i++)
    {
      (*l)->del(list_get(*l,i));
    }
  }
  list_exit_mutex(*l);
  rt_mutex_delete((*l)->mutex);
  free(*l);
  *l=0;
}






int list_block_size4(list_def *l)
{
  param_check(l);
  return l->block_size4;
}


//static void cpy4byte(uint32_t *dst,uint32_t *src,int num_4byte)
//{
//  for(int i=0;i<num_4byte;i++)
//  {
//    dst[i]=src[i];
//  }
//}



static list_def *list_expend(list_def *l)
{
  int size=0;
  int cpysize=0;
  list_def *r;
  size+=sizeof(list_def);
  size+=(sizeof(list_node_def)+l->block_size4)*(l->all);
  cpysize=size;
  size+=(sizeof(list_node_def)+l->block_size4)*(LIST_APPEND_SKIP);
  r=malloc(size);
  param_check(r);
  cpy4byte((uint32_t *)r,(uint32_t *)l,cpysize/4);
  // 初始化列表
  list_node_def *node;
  node=(list_node_def *)((uint32_t)r->data+r->all*(sizeof(list_node_def)+r->block_size4));
  for(int i=0;i<LIST_APPEND_SKIP;i++)
  {
    node->next=-1;
    node->prev=-1;
    node=(list_node_def *)((uint32_t)node+sizeof(list_node_def)+r->block_size4);
  }
  r->all+=LIST_APPEND_SKIP;
  free(l);
  return r;
}

// 查找一个未使用的节点
static list_node_def *list_unused_node(list_def *l,int *index)
{
  list_node_def *node=0;
  node=(list_node_def *)l->data;
  for(int i=0;i<l->all;i++)
  {
    if((node->next==-1)&&(node->prev==-1)){
      if(index) *index=i;
      return node;
    }
    node=(list_node_def *)((uint32_t)node+sizeof(list_node_def)+l->block_size4);
  }
  return node;
}

// 取得指定序号的节点
static list_node_def *list_node(list_def *l,int index)
{
  list_node_def *node;
  param_check(index>=0&&index<l->all);
  node=(list_node_def *)((uint32_t)l->data+index*(sizeof(list_node_def)+l->block_size4));
  return node;
}


// 取得节点的物理索引
static int list_phy_index(list_def *l,list_node_def *n)
{
  return ((uint32_t)n-(uint32_t)l->data)/(sizeof(list_node_def)+l->block_size4);
}


/*
// 改为统一使用insert函数
list_def *list_append(list_def **l,void *data)
{
  param_check(l);
  param_check(*l);
  list_def *r=*l;
  if((*l)->used>=(*l)->all)
  {
    r=list_expend(*l);
  }
  list_node_def *node;
  int index;
  node=list_unused_node(r,&index);
  param_check(node);
  memcpy(node->data,data,r->block_size);
  if(r->head==-1&&r->tail==-1)
  {
    r->head=index;
    r->tail=index;
    node->next=index;
    node->prev=index;
  }
  else if(r->head!=-1&&r->tail!=-1)
  {
    node->prev=r->tail;
    node->next=list_node(r,r->tail)->next;
    list_node(r,r->tail)->next=index;
    r->tail=index;
    list_node(r,r->head)->prev=index;
  }
  else
  {
    param_check(0);
  }
  r->used++;
  *l=r;
  return r;
}
*/



// 返回指定index的已使用节点
static list_node_def *list_used_node(list_def *l,int index)
{
  list_node_def *node=0;
  if(index>l->used/2)
  {
    index=l->used-1-index;
    node=list_node(l,l->tail);
    for(int i=0;i<index;i++)
    {
      node=list_node(l,node->prev);
    }
  }
  else{
    node=list_node(l,l->head);
    for(int i=0;i<index;i++)
    {
      node=list_node(l,node->next);
    }
  }
  return node;
}





// 获取第index项数据,不删除
// index支持负数，-1表示最后一项
// 返回数据引用
void *list_get(list_def *l,int index)
{
  param_check(l);
  void *ret=0;
  list_enter_mutex(l);
  list_node_def *node;
  if(index<0) index=l->used+index;
  if((index>=0&&index<l->used)==0)
    ret=0;
  else{
    node=list_used_node(l,index);
    param_check(node);
    ret=node->data;
  }
  list_exit_mutex(l);
  return ret;
}


// 删除第index项数据
// index支持负数，-1表示最后一项
void list_remove(list_def *l,int index)
{
  param_check(l);
  list_node_def *node;
  int phy_index;
  if(index<0) index=l->used+index;
  list_enter_mutex(l);
  if((index>=0&&index<l->used)){
    node=list_used_node(l,index);
    param_check(node);
    phy_index=list_phy_index(l,node);
    if(l->used==1)
    {
      l->head=-1;
      l->tail=-1;
    }
    else
    {
      if(l->head==phy_index)
      {
        l->head=node->next;
      }
      if(l->tail==phy_index)
      {
        l->tail=node->prev;
      }
      list_node(l,node->prev)->next=node->next;
      list_node(l,node->next)->prev=node->prev;
    }
    node->next=-1;
    node->prev=-1;
    if(l->del) l->del(node->data);
    l->used--;
  }
  list_enter_mutex(l);
}


// 获取指定index的数据，随后删除
// 返回数据的临时指针
// 对于存在动态指针的对象，由于take之后会自动删除，take操作会出现野指针
// 建议使用list_get + list_remove的方式代替list_take
void *list_take(list_def *l,int index)
{
  param_check(l);
  void *p;
  p=list_get(l,index);
  void *t=tmalloc(l->block_size);
  param_check(t);
  memcpy(t,p,l->block_size);
  list_remove(l,index);
  return t;
}


// 清空
void list_clear(list_def *l)
{
  param_check(l);
  list_enter_mutex(l);
  while(l->used>0)
  {
    list_remove(l,0);
  }
  list_exit_mutex(l);
}


int list_length(list_def *l)
{
  param_check(l);
  return l->used;
}




// 在指定位置插入
// index为节点插入之后所在的位置
list_def *_list_insert(list_def **l,void *data,int index)
{
  param_check(l);
  param_check(*l);
  list_enter_mutex(*l);
  if(index<0) index=(*l)->used+index+1;
  if((index>=0&&index<=(*l)->used)==0){
    list_exit_mutex(*l);
    return *l;
  }
  list_def *r=*l;
  if((*l)->used>=(*l)->all)
  {
    r=list_expend(*l);
  }
  list_node_def *node;
  int phy_index;
  node=list_unused_node(r,&phy_index);
  param_check(node);
  memcpy(node->data,data,r->block_size);
  if(r->head==-1&&r->tail==-1)
  {
    r->head=phy_index;
    r->tail=phy_index;
    node->next=phy_index;
    node->prev=phy_index;
  }
  else if(r->head!=-1&&r->tail!=-1)
  {
    list_node_def *n;
    int n_phy_index;
    if(index<r->used)
    {
      n=list_used_node(r,index);
      n_phy_index=list_phy_index(r,n);
      list_node(r,n->prev)->next=phy_index;
      node->prev=n->prev;
      node->next=n_phy_index;
      n->prev=phy_index;
      if(index==0)
      {
        r->head=phy_index;
      }
    }
    else
    {
      node->prev=r->tail;
      node->next=list_node(r,r->tail)->next;
      list_node(r,r->tail)->next=phy_index;
      r->tail=index;
      list_node(r,r->head)->prev=phy_index;
    }
  }
  else
  {
    param_check(0);
  }
  r->used++;
  *l=r;
  list_exit_mutex(*l);
  return r;
}


void list_sort(list_def *l)
{
  param_check(l);
  list_enter_mutex(l);
  if(l->sub){
    _list_sort(l,l->sub);
  }
  else{
    DBG_WARN("obj->sub fun is null.");
  }
  list_exit_mutex(l);
}




// 在列表内返回1，不在返回0
int list_contains(list_def *l,void *d)
{
  param_check(l);
  list_enter_mutex(l);
  if(l->sub)
  {
    for(int i=0;i<list_length(l);i++)
    {
      if(l->sub(list_get(l,i),d)==0){
        list_exit_mutex(l);
        return 1;
      }
    }
  }
  else{
    DBG_WARN("obj->sub fun is null.");
  }
  list_exit_mutex(l);
  return 0;
}


// 交换两个位置
void list_swap(list_def *l,int index_a,int index_b)
{
  param_check(l);
  list_enter_mutex(l);
  void *a_=list_get(l,index_a);
  void *b_=list_get(l,index_b);
  void *t_=0;
  if(a_&&b_)
  {
    t_=calloc(1,sizeof(l->block_size4));
    cpy4byte(t_,a_,l->block_size4/4);
    cpy4byte(a_,b_,l->block_size4/4);
    cpy4byte(b_,t_,l->block_size4/4);
    free(t_);
  }
  list_exit_mutex(l);
}


// 向后循环移动
void list_shift(list_def *l)
{
  param_check(l);
  list_enter_mutex(l);
  if(l->used>0){
    l->head=list_node(l,l->head)->next;
    l->tail=list_node(l,l->tail)->next;
  }
  list_exit_mutex(l);
}





// 输出打印字符串
char *list_string(list_def *l)
{
  param_check(l);
  list_enter_mutex(l);
  array_def *d=arr_creat();
  param_check(d);
  int len=0;
  char *s=0;
  arr_append(d,'(');
  if(l->str)
  {
    for(int i=0;i<list_length(l);i++)
    {
      s=l->str(list_get(l,i));
      len=strlen(s);
      arr_appends(d,s,len);
      free(s);
      arr_append(d,',');
      arr_append(d,' ');
    }
  }
  arr_append(d,')');
  len=arr_length(d);
  s=malloc(len+1);
  param_check(s);
  memcpy(s,arr_data(d),len);
  arr_delete(d);
  s[len]=0;
  list_exit_mutex(l);
  return s;
}





// int sub函数
int _list_int_sub(void *a,void *b)
{
  return *(int *)a-*(int *)b;
}


// int 打印函数
char *_list_int_str(void *a)
{
  char *s=malloc(20);
  param_check(s);
  sprintf(s,"%d",*(int *)a);
  return s;
}


// str sub函数
int _list_str_sub(void *a,void *b)
{
  char *a_=*(char **)a;
  char *b_=*(char **)b;
  return strcmp(a_,b_);
}


// str删除函数
int _list_str_del(void *d)
{
  char **c=d;
  if(*c) free(*c);
  return 0;
}

// str 打印函数
char *_list_str_str(void *a)
{
  char *a_=*(char **)a;
  int len=strlen(a_);
  char *s=malloc(len+1);
  param_check(s);
  memcpy(s,a_,len+1);
  return s;
}



// 延迟删除，不需要修改指针
void _list_delete_later(list_def *l)
{
  _list_delete(&l);
}



