/*
Andrea Marin
correzione dell'esame del 18/06/2010
*/

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

/*si e' adottata la soluzione piu' semplice di riservare uno spazio
massimo per le stringhe nel nodo*/


struct nodo {
    char id[100];   /*identificatore*/
    char indirizzo[100]; /*indirizzo*/
    struct nodo* next;
};


typedef struct nodo* t_preferiti;


/*inserimento*/
t_preferiti inserisci(t_preferiti lista, char* ident, char* indir) {
    t_preferiti nuovo;
    nuovo = malloc(sizeof(struct nodo));
    if (nuovo) {  /*allocazione avvenuta con successo*/
       strcpy(nuovo->id, ident);
       strcpy(nuovo->indirizzo, indir);
       nuovo->next=lista;
    }
    return nuovo;
}

/*cancellazione: la difficolta' di questa procedura (se iterativa) sta nella
differenza che esiste tra l'eliminare un elemento in mezzo alla lista
e l'eliminare un elemento in testa alla lista. Una soluzione ricorsiva
risolve il problema elegantemente*/
t_preferiti cancella(t_preferiti lista, char* ident) {
   if (lista) {
      lista->next = cancella(lista->next, ident); /*elimina tutte le occorrenze dalla coda*/
      if (strcmp(lista->id, ident)) { /*la testa non contiene l'id da eliminare*/
         return lista;
      }
      else { /*la testa va eliminata*/
         t_preferiti nuova = lista->next;
         free(lista);
         return nuova;
      }
   }
}



void estrai_prefisso(char* buffer, char* str) {
    while (*str && (*str!='/' || *str=='/' && *(str+1)=='/')) {
       *buffer = *str;
       if (*str=='/') {/*certamente e' seguita da un'altra barra*/
          buffer++; 
          str++;
          *buffer=*str;
       }
       buffer++;
       str++;
    }
    *buffer = '\0';
}


/*identica alla cancella, ma lavora sui prefissi degli indirizzi*/ 
t_preferiti cancella_indirizzo(t_preferiti lista, char* indirizzo) {
   if (lista) {
      lista->next = cancella_indirizzo(lista->next, indirizzo);
      char buf[100];
      estrai_prefisso(buf, lista->indirizzo);
      if (strcmp(buf, indirizzo)) { 
         return lista;
      }
      else { /*la testa va eliminata*/
         t_preferiti nuova = lista->next;
         free(lista);
         return nuova;
      }
   }   
}

void stampa_lista(t_preferiti lista) { /*procedura di controllo*/
    if (lista) {
       printf("%s *** %s \n", lista->id, lista->indirizzo);
       stampa_lista(lista->next);
    }
}


/*elimina i duplicati*/
t_preferiti elimina_duplicati(t_preferiti lista) {
    if (lista) {
       char buff[100];
       estrai_prefisso(buff, lista->indirizzo);
       lista->next=cancella_indirizzo(lista->next, buff);  /*elimina i duplicati dalla coda*/
       lista->next=elimina_duplicati(lista->next); /*pulisci la coda dai duplicati*/
    }
    return lista;
}
        




int main() {
    t_preferiti l = NULL;
    l = inserisci(l, "Google", "http://www.google.com");
    l = inserisci(l, "prova", "http://www.prova.com/calendar");
    l = inserisci(l, "Calendar", "http://www.google.com/calendar");
    l = inserisci(l, "Maps", "http://www.google.com/maps");
    l = inserisci(l, "Google", "http://www.google.it");
    l = inserisci(l, "other", "http://www.prova.com/ca");
    stampa_lista(l);
    l = elimina_duplicati(l);
    printf("\n\n\n");
    stampa_lista(l);
    return 0;
}



