/**
 * \File playlist-spl.c
 *
 * Playlist_t to Samsung (.spl) and back conversion functions.
 *
 * Copyright (C) 2008 Alistair Boyle <alistair.js.boyle@gmail.com>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library 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.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 */

#include <config.h>

#include <stdio.h>
#include <stdlib.h> // mkstmp()
#include <unistd.h>
#include <errno.h>
#include <sys/stat.h>
#include <sys/types.h>
#ifdef HAVE_SYS_UIO_H
#include <sys/uio.h>
#endif
#include <fcntl.h>

#include <string.h>

#include "libmtp.h"
#include "libusb-glue.h"
#include "ptp.h"
#include "unicode.h"

#include "playlist-spl.h"

// set this to 1 to add lots of messy debug output to the playlist code
#define DEBUG_ENABLED 0

// debug macro
// d = indenting depth
#define IF_DEBUG() if(DEBUG_ENABLED) {\
                     printf("%s:%u:%s(): ", __FILE__, __LINE__, __func__); \
                   } \
                   if(DEBUG_ENABLED)

// Internal singly linked list of strings
// used to hold .spl playlist in memory
typedef struct text_struct {
  char* text; // String
  struct text_struct *next; // Link to next line, NULL if end of list
} text_t;


/**
 * Forward declarations of local (static) functions.
 */
static text_t* read_into_spl_text_t(LIBMTP_mtpdevice_t *device, const int fd);
static void write_from_spl_text_t(LIBMTP_mtpdevice_t *device, const int fd, text_t* p);
static void free_spl_text_t(text_t* p);
static void print_spl_text_t(text_t* p);
static uint32_t trackno_spl_text_t(text_t* p);
static void tracks_from_spl_text_t(text_t* p, uint32_t* tracks, LIBMTP_folder_t* folders, LIBMTP_file_t* files);
static void spl_text_t_from_tracks(text_t** p, uint32_t* tracks, const uint32_t trackno, const uint32_t ver_major, const uint32_t ver_minor, char* dnse, LIBMTP_folder_t* folders, LIBMTP_file_t* files);

static uint32_t discover_id_from_filepath(const char* s, LIBMTP_folder_t* folders, LIBMTP_file_t* files); // TODO add file/dir cached args
static void discover_filepath_from_id(char** p, uint32_t track, LIBMTP_folder_t* folders, LIBMTP_file_t* files);
static void find_folder_name(LIBMTP_folder_t* folders, uint32_t* id, char** name);
static uint32_t find_folder_id(LIBMTP_folder_t* folders, uint32_t parent, char* name);

static void append_text_t(text_t** t, char* s);




/**
 * Decides if the indicated object index is an .spl playlist.
 *
 * @param oi object we are deciding on
 * @return 1 if this is a Samsung .spl object, 0 otherwise
 */
int is_spl_playlist(PTPObjectInfo *oi)
{
  return (oi->ObjectFormat == PTP_OFC_Undefined) &&
         (strlen(oi->Filename) > 4) &&
         (strcmp((oi->Filename + strlen(oi->Filename) -4), ".spl") == 0);
}

#ifndef HAVE_MKSTEMP
# ifdef __WIN32__
#  include <fcntl.h>
#  define mkstemp(_pattern) _open(_mktemp(_pattern), _O_CREAT | _O_SHORT_LIVED | _O_EXCL)
# else
#  error Missing mkstemp() function.
# endif
#endif

/**
 * Take an object ID, a .spl playlist on the MTP device,
 * and convert it to a playlist_t object.
 *
 * @param device mtp device pointer
 * @param oi object we are reading
 * @param id .spl playlist id on MTP device
 * @param pl the LIBMTP_playlist_t pointer to be filled with info from id
 */

void spl_to_playlist_t(LIBMTP_mtpdevice_t* device, PTPObjectInfo *oi,
                       const uint32_t id, LIBMTP_playlist_t * const pl)
{
  // Fill in playlist metadata
  // Use the Filename as the playlist name, dropping the ".spl" extension
  pl->name = malloc(sizeof(char)*(strlen(oi->Filename) -4 +1));
  memcpy(pl->name, oi->Filename, strlen(oi->Filename) -4);
  // Set terminating character
  pl->name[strlen(oi->Filename) - 4] = 0;
  pl->playlist_id = id;
  pl->parent_id = oi->ParentObject;
  pl->storage_id = oi->StorageID;
  pl->tracks = NULL;
  pl->no_tracks = 0;

  IF_DEBUG() printf("pl->name='%s'\n",pl->name);

  // open a temporary file
  char tmpname[] = "/tmp/mtp-spl2pl-XXXXXX";
  int fd = mkstemp(tmpname);
  if(fd < 0) {
    printf("failed to make temp file for %s.spl -> %s, errno=%s\n", pl->name, tmpname, strerror(errno));
    return;
  }
  // make sure the file will be deleted afterwards
  if(unlink(tmpname) < 0)
    printf("failed to delete temp file for %s.spl -> %s, errno=%s\n", pl->name, tmpname, strerror(errno));
  int ret = LIBMTP_Get_File_To_File_Descriptor(device, pl->playlist_id, fd, NULL, NULL, NULL);
  if( ret < 0 ) {
    // FIXME     add_ptp_error_to_errorstack(device, ret, "LIBMTP_Get_Playlist: Could not get .spl playlist file.");
    close(fd);
    printf("FIXME closed\n");
  }

  text_t* p = read_into_spl_text_t(device, fd);
  close(fd);

  // FIXME cache these somewhere else so we don't keep calling this!
  LIBMTP_folder_t *folders;
  LIBMTP_file_t *files;
  folders = LIBMTP_Get_Folder_List(device);
  files = LIBMTP_Get_Filelisting_With_Callback(device, NULL, NULL);

  // convert the playlist listing to track ids
  pl->no_tracks = trackno_spl_text_t(p);
  IF_DEBUG() printf("%u track%s found\n", pl->no_tracks, pl->no_tracks==1?"":"s");
  pl->tracks = malloc(sizeof(uint32_t)*(pl->no_tracks));
  tracks_from_spl_text_t(p, pl->tracks, folders, files);

  free_spl_text_t(p);

  // debug: add a break since this is the top level function call
  IF_DEBUG() printf("------------\n\n");
}


/**
 * Push a playlist_t onto the device after converting it to a .spl format
 *
 * @param device mtp device pointer
 * @param pl the LIBMTP_playlist_t to convert (pl->playlist_id will be updated
 *           with the newly created object's id)
 * @return 0 on success, any other value means failure.
 */
int playlist_t_to_spl(LIBMTP_mtpdevice_t *device,
                      LIBMTP_playlist_t * const pl)
{
  text_t* t;
  LIBMTP_folder_t *folders;
  LIBMTP_file_t *files;
  folders = LIBMTP_Get_Folder_List(device);
  files = LIBMTP_Get_Filelisting_With_Callback(device, NULL, NULL);

  char tmpname[] = "/tmp/mtp-spl2pl-XXXXXX"; // must be a var since mkstemp modifies it

  IF_DEBUG() printf("pl->name='%s'\n",pl->name);

  // open a file descriptor
  int fd = mkstemp(tmpname);
  if(fd < 0) {
    printf("failed to make temp file for %s.spl -> %s, errno=%s\n", pl->name, tmpname, strerror(errno));
    return -1;
  }
  // make sure the file will be deleted afterwards
  if(unlink(tmpname) < 0)
    printf("failed to delete temp file for %s.spl -> %s, errno=%s\n", pl->name, tmpname, strerror(errno));

  // decide on which version of the .spl format to use
  uint32_t ver_major;
  uint32_t ver_minor = 0;
  PTP_USB *ptp_usb = (PTP_USB*) device->usbinfo;
  if(FLAG_PLAYLIST_SPL_V2(ptp_usb)) ver_major = 2;
  else ver_major = 1; // FLAG_PLAYLIST_SPL_V1()

  IF_DEBUG() printf("%u track%s\n", pl->no_tracks, pl->no_tracks==1?"":"s");
  IF_DEBUG() printf(".spl version %d.%02d\n", ver_major, ver_minor);

  // create the text for the playlist
  spl_text_t_from_tracks(&t, pl->tracks, pl->no_tracks, ver_major, ver_minor, NULL, folders, files);
  write_from_spl_text_t(device, fd, t);
  free_spl_text_t(t); // done with the text

  // create the file object for storing
  LIBMTP_file_t* f = malloc(sizeof(LIBMTP_file_t));
  f->item_id = 0;
  f->parent_id = pl->parent_id;
  f->storage_id = pl->storage_id;
  f->filename = malloc(sizeof(char)*(strlen(pl->name)+5));
  strcpy(f->filename, pl->name);
  strcat(f->filename, ".spl"); // append suffix
  f->filesize = lseek(fd, 0, SEEK_CUR); // file desc is currently at end of file
  f->filetype = LIBMTP_FILETYPE_UNKNOWN;
  f->next = NULL;

  IF_DEBUG() printf("%s is %dB\n", f->filename, (int)f->filesize);

  // push the playlist to the device
  lseek(fd, 0, SEEK_SET); // reset file desc. to start of file
  int ret = LIBMTP_Send_File_From_File_Descriptor(device, fd, f, NULL, NULL);
  pl->playlist_id = f->item_id;
  free(f->filename);
  free(f);

  // release the memory when we're done with it
  close(fd);
  // debug: add a break since this is the top level function call
  IF_DEBUG() printf("------------\n\n");

  return ret;
}



/**
 * Update a playlist on the device. If only the playlist's name is being
 * changed the pl->playlist_id will likely remain the same. An updated track
 * list will result in the old playlist being replaced (ie: new playlist_id).
 * NOTE: Other playlist metadata aside from playlist name and tracks are
 * ignored.
 *
 * @param device mtp device pointer
 * @param new the LIBMTP_playlist_t to convert (pl->playlist_id will be updated
 *           with the newly created object's id)
 * @return 0 on success, any other value means failure.
 */
int update_spl_playlist(LIBMTP_mtpdevice_t *device,
			  LIBMTP_playlist_t * const newlist)
{
  IF_DEBUG() printf("pl->name='%s'\n",newlist->name);

  // read in the playlist of interest
  LIBMTP_playlist_t * old = LIBMTP_Get_Playlist(device, newlist->playlist_id);
  
  // check to see if we found it
  if (!old)
    return -1;

  // check if the playlists match
  int delta = 0;
  int i;
  if(old->no_tracks != newlist->no_tracks)
    delta++;
  for(i=0;i<newlist->no_tracks && delta==0;i++) {
    if(old->tracks[i] != newlist->tracks[i])
      delta++;
  }

  // if not, kill the playlist and replace it
  if(delta) {
    IF_DEBUG() printf("new tracks detected:\n");
    IF_DEBUG() printf("delete old playlist and build a new one\n");
    IF_DEBUG() printf(" NOTE: new playlist_id will result!\n");
    if(LIBMTP_Delete_Object(device, old->playlist_id) != 0)
      return -1;

    IF_DEBUG() {
      if(strcmp(old->name,newlist->name) == 0)
        printf("name unchanged\n");
      else
        printf("name is changing too -> %s\n",newlist->name);
    }

    return LIBMTP_Create_New_Playlist(device, newlist);
  }


  // update the name only
  if(strcmp(old->name,newlist->name) != 0) {
    IF_DEBUG() printf("ONLY name is changing -> %s\n",newlist->name);
    IF_DEBUG() printf("playlist_id will remain unchanged\n");
    char* s = malloc(sizeof(char)*(strlen(newlist->name)+5));
    strcpy(s, newlist->name);
    strcat(s,".spl"); // FIXME check for success
    int ret = LIBMTP_Set_Playlist_Name(device, newlist, s);
    free(s);
    return ret;
  }

  IF_DEBUG() printf("no change\n");
  return 0; // nothing to be done, success
}


/**
 * Load a file descriptor into a string.
 *
 * @param device a pointer to the current device.
 *               (needed for ucs2->utf8 charset conversion)
 * @param fd the file descriptor to load
 * @return text_t* a linked list of lines of text, id is left blank, NULL if nothing read in
 */
static text_t* read_into_spl_text_t(LIBMTP_mtpdevice_t *device, const int fd)
{
  // set MAXREAD to match STRING_BUFFER_LENGTH in unicode.h conversion function
  const size_t MAXREAD = 1024*2;
  char t[MAXREAD];
  // upto 3 bytes per utf8 character, 2 bytes per ucs2 character,
  // +1 for '\0' at end of string
  const size_t WSIZE = MAXREAD/2*3+1;
  char w[WSIZE];
  char* it = t; // iterator on t
  char* iw = w;
  ssize_t rdcnt;
  off_t offcnt;
  text_t* head = NULL;
  text_t* tail = NULL;
  int eof = 0;

  // reset file descriptor (fd) to start of file
  offcnt = lseek(fd, 0, SEEK_SET);

  while(!eof) {
    // find the current offset in the file
    // to allow us to determine how many bytes we read if we hit the EOF
    // where returned rdcnt=0 from read()
    offcnt = lseek(fd, 0, SEEK_CUR);
    // read to refill buffer
    // (there might be data left from an incomplete last string in t,
    // hence start filling at it)
    it = t; // set ptr to start of buffer
    rdcnt = read(fd, it, sizeof(char)*MAXREAD);
    if(rdcnt < 0)
      printf("load_spl_fd read err %s\n", strerror(errno));
    else if(rdcnt == 0) { // for EOF, fix rdcnt
      if(it-t == MAXREAD)
        printf("error -- buffer too small to read in .spl playlist entry\n");

      rdcnt = lseek(fd, 0, SEEK_CUR) - offcnt;
      eof = 1;
    }

    IF_DEBUG() printf("read buff= {%dB new, %dB old/left-over}%s\n",(int)rdcnt, (int)(iw-w), eof?", EOF":"");

    // while more input bytes
    char* it_end = t + rdcnt;
    while(it < it_end) {
      // copy byte, unless EOL (then replace with end-of-string \0)
      if(*it == '\r' || *it == '\n')
        *iw = '\0';
      else
        *iw = *it;

      it++;
      iw++;

      // EOL -- store it
      if( (iw-w) >= 2 && // we must have at least two bytes
          *(iw-1) == '\0' && *(iw-2) == '\0' && // 0x0000 is end-of-string
          // but it must be aligned such that we have an {odd,even} set of
          // bytes since we are expecting to consume bytes two-at-a-time
          !((iw-w)%2) ) {

        // drop empty lines
        //  ... cast as a string of 2 byte characters
        if(ucs2_strlen((uint16_t*)w) == 0) {
          iw = w;
          continue;
        }

        // create a new node in the list
        if(head == NULL) {
          head = malloc(sizeof(text_t));
          tail = head;
        }
        else {
          tail->next = malloc(sizeof(text_t));
          tail = tail->next;
        }
        // fill in the data for the node
        //  ... cast as a string of 2 byte characters
        tail->text = utf16_to_utf8(device, (uint16_t*) w);
        iw = w; // start again

        IF_DEBUG() printf("line: %s\n", tail->text);
      }

      // prevent buffer overflow
      if(iw >= w + WSIZE) {
        // if we ever see this error its BAD:
        //   we are dropping all the processed bytes for this line and
        //   proceeding on as if everything is okay, probably losing a track
        //   from the playlist
        printf("ERROR %s:%u:%s(): buffer overflow! .spl line too long @ %zuB\n",
               __FILE__, __LINE__, __func__, WSIZE);
        iw = w; // reset buffer
      }
    }

    // if the last thing we did was save our line, then we finished working
    // on the input buffer and we can start fresh
    // otherwise we need to save our partial work, if we're not quiting (eof).
    // there is nothing special we need to do, to achieve this since the
    // partially completed string will sit in 'w' until we return to complete
    // the line

  }

  // set the next pointer at the end
  // if there is any list
  if(head != NULL)
    tail->next = NULL;

  // return the head of the list (NULL if no list)
  return head;
}


/**
 * Write a .spl text file to a file in preparation for pushing it
 * to the device.
 *
 * @param fd file descriptor to write to
 * @param p the text to output one line per string in the linked list
 * @see playlist_t_to_spl()
 */
static void write_from_spl_text_t(LIBMTP_mtpdevice_t *device,
                                  const int fd,
                                  text_t* p) {
  ssize_t ret;
  // write out BOM for utf16/ucs2 (byte order mark)
  ret = write(fd,"\xff\xfe",2);
  while(p != NULL) {
    char *const t = (char*) utf8_to_utf16(device, p->text);
    // note: 2 bytes per ucs2 character
    const size_t len = ucs2_strlen((uint16_t*)t)*sizeof(uint16_t);
    int i;

    IF_DEBUG() {
      printf("\nutf8=%s ",p->text);
      for(i=0;i<strlen(p->text);i++)
        printf("%02x ", p->text[i] & 0xff);
      printf("\n");
      printf("ucs2=");
      for(i=0;i<ucs2_strlen((uint16_t*)t)*sizeof(uint16_t);i++)
        printf("%02x ", t[i] & 0xff);
      printf("\n");
    }

    // write: utf8 -> utf16
    ret += write(fd, t, len);

    // release the converted string
    free(t);

    // check for failures
    if(ret < 0)
      printf("write spl file failed: %s\n", strerror(errno));
    else if(ret != len +2)
      printf("write spl file wrong number of bytes ret=%d len=%d '%s'\n", (int)ret, (int)len, p->text);

    // write carriage return, line feed in ucs2
    ret = write(fd, "\r\0\n\0", 4);
    if(ret < 0)
      printf("write spl file failed: %s\n", strerror(errno));
    else if(ret != 4)
      printf("failed to write the correct number of bytes '\\n'!\n");

    // fake out count (first time through has two extra bytes from BOM)
    ret = 2;

    // advance to the next line
    p = p->next;
  }
}

/**
 * Destroy a linked-list of strings.
 *
 * @param p the list to destroy
 * @see spl_to_playlist_t()
 * @see playlist_t_to_spl()
 */
static void free_spl_text_t(text_t* p)
{
  text_t* d;
  while(p != NULL) {
    d = p;
    free(p->text);
    p = p->next;
    free(d);
  }
}

/**
 * Print a linked-list of strings to stdout.
 *
 * @param p the list to print
 */
static void print_spl_text_t(text_t* p)
{
  while(p != NULL) {
    printf("%s\n",p->text);
    p = p->next;
  }
}

/**
 * Count the number of tracks in this playlist. A track will be counted as
 * such if the line starts with a leading slash.
 *
 * @param p the text to search
 * @return number of tracks in the playlist
 * @see spl_to_playlist_t()
 */
static uint32_t trackno_spl_text_t(text_t* p) {
  uint32_t c = 0;
  while(p != NULL) {
    if(p->text[0] == '\\' ) c++;
    p = p->next;
  }

  return c;
}

/**
 * Find the track ids for this playlist's files.
 * (ie: \Music\song.mp3 -> 12345)
 *
 * @param p the text to search
 * @param tracks returned list of track id's for the playlist_t, must be large
 *               enough to accomodate all the tracks as reported by
 *               trackno_spl_text_t()
 * @param folders the folders list for the device
 * @param fiels the files list for the device
 * @see spl_to_playlist_t()
 */
static void tracks_from_spl_text_t(text_t* p,
                                   uint32_t* tracks,
                                   LIBMTP_folder_t* folders,
                                   LIBMTP_file_t* files)
{
  uint32_t c = 0;
  while(p != NULL) {
    if(p->text[0] == '\\' ) {
      tracks[c] = discover_id_from_filepath(p->text, folders, files);
      IF_DEBUG()
        printf("track %d = %s (%u)\n", c+1, p->text, tracks[c]);
      c++;
    }
    p = p->next;
  }
}


/**
 * Find the track names (including path) for this playlist's track ids.
 * (ie: 12345 -> \Music\song.mp3)
 *
 * @param p the text to search
 * @param tracks list of track id's to look up
 * @param folders the folders list for the device
 * @param fiels the files list for the device
 * @see playlist_t_to_spl()
 */
static void spl_text_t_from_tracks(text_t** p,
                                   uint32_t* tracks,
                                   const uint32_t trackno,
                                   const uint32_t ver_major,
                                   const uint32_t ver_minor,
                                   char* dnse,
                                   LIBMTP_folder_t* folders,
                                   LIBMTP_file_t* files)
{

  // HEADER
  text_t* c = NULL;
  append_text_t(&c, "SPL PLAYLIST");
  *p = c; // save the top of the list!

  char vs[14]; // "VERSION 2.00\0"
  sprintf(vs,"VERSION %d.%02d",ver_major,ver_minor);

  append_text_t(&c, vs);
  append_text_t(&c, "");

  // TRACKS
  int i;
  char* f;
  for(i=0;i<trackno;i++) {
    discover_filepath_from_id(&f, tracks[i], folders, files);

    if(f != NULL) {
      append_text_t(&c, f);
      IF_DEBUG()
        printf("track %d = %s (%u)\n", i+1, f, tracks[i]);
    }
    else
      printf("failed to find filepath for track=%d\n", tracks[i]);
  }

  // FOOTER
  append_text_t(&c, "");
  append_text_t(&c, "END PLAYLIST");
  if(ver_major == 2) {
    append_text_t(&c, "");
    append_text_t(&c, "myDNSe DATA");
    if(dnse != NULL) {
      append_text_t(&c, dnse);
    }
    else {
      append_text_t(&c, "");
      append_text_t(&c, "");
    }
    append_text_t(&c, "END myDNSe");
  }

  c->next = NULL;

  // debug
  IF_DEBUG() {
    printf(".spl playlist:\n");
    print_spl_text_t(*p);
  }
}


/**
 * Find the track names (including path) given a fileid
 * (ie: 12345 -> \Music\song.mp3)
 *
 * @param p returns the file path (ie: \Music\song.mp3),
 *          (*p) == NULL if the look up fails
 * @param track track id to look up
 * @param folders the folders list for the device
 * @param files the files list for the device
 * @see spl_text_t_from_tracks()
 */

// returns p = NULL on failure, else the filepath to the track including track name, allocated as a correct length string
static void discover_filepath_from_id(char** p,
                                      uint32_t track,
                                      LIBMTP_folder_t* folders,
                                      LIBMTP_file_t* files)
{
  // fill in a string from the right side since we don't know the root till the end
  const int M = 1024;
  char w[M];
  char* iw = w + M; // iterator on w

  // in case of failure return NULL string
  *p = NULL;


  // find the right file
  while(files != NULL && files->item_id != track) {
    files = files->next;
  }
  // if we didn't find a matching file, abort
  if(files == NULL)
    return;

  // stuff the filename into our string
  // FIXME: check for string overflow before it occurs
  iw = iw - (strlen(files->filename) +1); // leave room for '\0' at the end
  strcpy(iw,files->filename);

  // next follow the directories to the root
  // prepending folders to the path as we go
  uint32_t id = files->parent_id;
  char* f = NULL;
  while(id != 0) {
    find_folder_name(folders, &id, &f);
    if(f == NULL) return; // fail if the next part of the path couldn't be found
    iw = iw - (strlen(f) +1);
    // FIXME: check for string overflow before it occurs
    strcpy(iw, f);
    iw[strlen(f)] = '\\';
    free(f);
  }

  // prepend a slash
  iw--;
  iw[0] = '\\';

  // now allocate a string of the right length to be returned
  *p = strdup(iw);
}


/**
 * Find the track id given a track's name (including path)
 * (ie: \Music\song.mp3 -> 12345)
 *
 * @param s file path to look up (ie: \Music\song.mp3),
 *          (*p) == NULL if the look up fails
 * @param folders the folders list for the device
 * @param files the files list for the device
 * @return track id, 0 means failure
 * @see tracks_from_spl_text_t()
 */
static uint32_t discover_id_from_filepath(const char* s, LIBMTP_folder_t* folders, LIBMTP_file_t* files)
{
  // abort if this isn't a path
  if(s[0] != '\\')
    return 0;

  int i;
  uint32_t id = 0;
  char* sc = strdup(s);
  char* sci = sc +1; // iterator
  // skip leading slash in path

  // convert all \ to \0
  size_t len = strlen(s);
  for(i=0;i<len;i++) {
    if(sc[i] == '\\') {
      sc[i] = '\0';
    }
  }

  // now for each part of the string, find the id
  while(sci != sc + len +1) {
    // if its the last part of the string, its the filename
    if(sci + strlen(sci) == sc + len) {

      while(files != NULL) {
        // check parent matches id and name matches sci
        if( (files->parent_id == id) &&
            (strcmp(files->filename, sci) == 0) ) { // found it!
          id = files->item_id;
          break;
        }
        files = files->next;
      }
    }
    else { // otherwise its part of the directory path
      id = find_folder_id(folders, id, sci);
    }

    // move to next folder/file
    sci += strlen(sci) +1;
  }

  // release our copied string
  free(sc);

  // FIXME check that we actually have a file

  return id;
}



/**
 * Find the folder name given the folder's id.
 *
 * @param folders the folders list for the device
 * @param id the folder_id to look up, returns the folder's parent folder_id
 * @param name returns the name of the folder or NULL on failure
 * @see discover_filepath_from_id()
 */
static void find_folder_name(LIBMTP_folder_t* folders, uint32_t* id, char** name)
{

  // FIXME this function is exactly LIBMTP_Find_Folder

  LIBMTP_folder_t* f = LIBMTP_Find_Folder(folders, *id);
  if(f == NULL) {
    *name = NULL;
  }
  else { // found it!
    *name = strdup(f->name);
    *id = f->parent_id;
  }
}


/**
 * Find the folder id given the folder's name and parent id.
 *
 * @param folders the folders list for the device
 * @param parent the folder's parent's id
 * @param name the name of the folder
 * @return the folder_id or 0 on failure
 * @see discover_filepath_from_id()
 */
static uint32_t find_folder_id(LIBMTP_folder_t* folders, uint32_t parent, char* name) {

  if(folders == NULL)
    return 0;

  // found it!
  else if( (folders->parent_id == parent) &&
           (strcmp(folders->name, name) == 0) )
    return folders->folder_id;

  // no luck so far, search both siblings and children
  else {
    uint32_t id = 0;

    if(folders->sibling != NULL)
      id = find_folder_id(folders->sibling, parent, name);
    if( (id == 0) && (folders->child != NULL) )
      id = find_folder_id(folders->child, parent, name);

    return id;
  }
}


/**
 * Append a string to a linked-list of strings.
 *
 * @param t the list-of-strings, returns with the added string
 * @param s the string to append
 * @see spl_text_t_from_tracks()
 */
static void append_text_t(text_t** t, char* s)
{
  if(*t == NULL) {
    *t = malloc(sizeof(text_t));
  }
  else {
    (*t)->next = malloc(sizeof(text_t));
    (*t) = (*t)->next;
  }
  (*t)->text = strdup(s);
}
