//**************************************************************************
//*                     This file is part of the                           *
//*                      Mpxplay - audio player.                           *
//*                  The source code of Mpxplay is                         *
//*        (C) copyright 1998-2011 by PDSoft (Attila Padar)                *
//*                http://mpxplay.sourceforge.net                          *
//*                  email: mpxplay@freemail.hu                            *
//**************************************************************************
//*  This program is distributed in the hope that it will be useful,       *
//*  but WITHOUT ANY WARRANTY; without even the implied warranty of        *
//*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                  *
//*  Please contact with the author (with me) if you want to use           *
//*  or modify this source.                                                *
//**************************************************************************
//function: http drive and file handling (http client)

#include "mpxplay.h"

#ifdef MPXPLAY_LINK_TCPIP

#include "diskdriv.h"
#include "tcpcomon.h"
#include <malloc.h>

extern ftpdrive_lowlevel_func_s HTTPDRV_lowlevel_funcs;

static ftpdrive_lowlevel_func_s *ALL_http_lowlevel_funcs[]={
 &HTTPDRV_lowlevel_funcs,  // 0.
 NULL
};

static void httpdrive_drive_unmount(void *drivehand_data);

static long httpdrive_drive_config(void *drive_data,unsigned long funcnum,void *argp1,void *argp2)
{
 return MPXPLAY_DISKDRIV_CFGERROR_UNSUPPFUNC;
}

static struct ftpdrive_lowlevel_func_s *httpdrive_drive_getlowfunc_by_name(char *name)
{
 struct ftpdrive_lowlevel_func_s **lowfunc=&ALL_http_lowlevel_funcs[0];
 do{
  if(pds_strlicmp(name,(*lowfunc)->name)==0)
   return (*lowfunc);
  lowfunc++;
 }while(*lowfunc);
 return NULL;
}

static unsigned int httpdrive_drive_check(char *pathname)
{
 if(httpdrive_drive_getlowfunc_by_name(pathname))
  return 1;
 return 0;
}

static unsigned int httpdrive_extract_logininfos_from_path(struct ftpdrive_info_s *ftpi,char *pathname)
{
 char *hostname,*portnum,*username,*password,*dirname,strtmp[MAX_PATHNAMELEN];

 funcbit_smp_pointer_put(ftpi->lowfunc,httpdrive_drive_getlowfunc_by_name(pathname));
 if(!ftpi->lowfunc)
  return 0;

 pathname+=pds_strlen(ftpi->lowfunc->name);

 while(*pathname=='/')
  pathname++;

 pds_strcpy(strtmp,pathname);
 hostname=pds_strrchr(strtmp,DRVFTP_PATHSEPARATOR_USER);
 if(hostname){
  *hostname++=0;
  username=&strtmp[0];
  password=pds_strchr(strtmp,DRVFTP_PATHSEPARATOR_PASSWORD);
  if(password)
   *password++=0;
  pds_strcpy(ftpi->username,username);
  pds_strcpy(ftpi->password,password);
 }else{
  hostname=&strtmp[0];
 }

 dirname=pds_strchr(hostname,PDS_DIRECTORY_SEPARATOR_CHAR_UNXFTP);
 if(dirname){
  pds_strcpy(ftpi->currremotedir_selected,dirname);
  *dirname=0;
 }
 portnum=pds_strchr(hostname,DRVFTP_PATHSEPARATOR_PORTNUM);
 if(portnum){
  *portnum++=0;
  funcbit_smp_value_put(ftpi->socket_info_session.portnum,pds_atol(portnum));
 }
 if(!ftpi->socket_info_session.portnum)
  funcbit_smp_value_put(ftpi->socket_info_session.portnum,ftpi->lowfunc->def_portnum);

 pds_strcpy(ftpi->servername,hostname);

 return 1;
}

static void *httpdrive_drive_connect(char *pathname)
{
 struct ftpdrive_info_s *ftpi=calloc(1,sizeof(*ftpi));
 if(!ftpi)
  return ftpi;
 if(!httpdrive_extract_logininfos_from_path(ftpi,pathname))
  goto err_out_connect;
 funcbit_enable(ftpi->flags,DRVFTP_FTPDRIVE_FLAG_HTTP);
 return ftpi;

err_out_connect:
 httpdrive_drive_unmount(ftpi);
 return NULL;
}

static void httpdrive_drive_unmount(void *drivehand_data)
{
 struct ftpdrive_info_s *ftpi=drivehand_data;
 if(ftpi){
  ftpi->lowfunc->socket_close(&ftpi->socket_info_session,1);
  tcpcomon_dircache_alldirs_dealloc(&ftpi->cdrvi);
  free(ftpi);
 }
}

static unsigned int httpdrive_findfirst(void *drivehand_data,char *pathname,unsigned int attrib,struct pds_find_t *ffblk)
{
 return 0;
}

static char *httpdrive_getcwd(void *drivehand_data,char *localpathbuf,unsigned int buflen)
{
 struct ftpdrive_info_s *ftpi=drivehand_data;
 *localpathbuf=0;
 if(ftpi->currremotedir_selected[0])
  tcpcomon_str_remotename_to_local(localpathbuf,ftpi->currremotedir_selected,buflen);
 return localpathbuf;
}

static int httpdrive_chdir(void *drivehand_data,char *path)
{
 struct ftpdrive_info_s *ftpi=drivehand_data;
 //struct tcpcomon_cached_directory_info_s *diri;
 int retcode=-1;
 char remotename[MAX_PATHNAMELEN];
 ftpi->connection_retry=DRVFTP_DEFAULT_TIMEOUTRETRY_SESSION;
 tcpcomon_str_localname_to_remote(remotename,path);
 retcode=0;
 /*diri=tcpcomon_dircache_dir_searchby_name(&ftpi->cdrvi,remotename);
 if(diri)
  retcode=0;
 else
  retcode=drvftp_cwd(ftpi,remotename);
 if(retcode==0)*/
  pds_strcpy(ftpi->currremotedir_selected,remotename);
 //else
 // drvftp_message_write_error(ftpi->lastresptext);
 return retcode;
}

struct mpxplay_drivehand_func_s HTTPDRIVE_drivehand_funcs={
 "HTTPDRIVE",
 MPXPLAY_DRIVEHANDFUNC_INFOBIT_SLOWACCESS,    // infobits
 &httpdrive_drive_config,
 &httpdrive_drive_check,
 &httpdrive_drive_connect,
 &httpdrive_drive_unmount,
 &httpdrive_findfirst,
 &diskdriv_ftpdrive_findnext,
 &diskdriv_ftpdrive_findclose,
 &httpdrive_getcwd,
 &httpdrive_chdir,
 NULL,
 NULL,
 NULL,
 NULL,
 NULL,  // r15
 NULL,  // r16
 NULL,  // r17
 NULL,  // r18
 NULL,  // r19
 NULL,  // r20

 NULL,//&ftpdrive_file_check,
 NULL,//&ftpdrive_file_open,
 NULL,//&ftpdrive_file_close,
 NULL,//&ftpdrive_file_read,
 NULL,
 NULL,//&ftpdrive_file_seek,
 NULL,//&ftpdrive_file_tell,
 NULL,//&ftpdrive_file_length,
 NULL,//&ftpdrive_file_eof,
 NULL,  // file_chsize
 NULL   // r31
};

#else // MPXPLAY_LINK_TCPIP

struct mpxplay_drivehand_func_s HTTPDRIVE_drivehand_funcs={
 "HTTPDRIVE",0,
 NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
 NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
 NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL
};

#endif
