// Emacs style mode select -*- C++ -*-
//------------------------------------------------------------------------
//
// Copyright(c) 2001, 2002 Simon Howard
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
// 
// 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.  See the
// GNU General Public License for more details.
// 
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
//
//--------------------------------------------------------------------------
//
// Parse options from cfg file
//
// This would be better if it was done in XML or something, but whatever
//
//------------------------------------------------------------------------

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

#include "parse.h"
#include "ui.h"

// all the machines

int num_machines;
machine_t **machines;

// all the clusters

cluster_t **clusters;
int num_clusters;

// read line from file
// cut off beginning and ending spaces
// ignore comments

static char *read_line(FILE *instream)
{
        static char inbuf[1024];
        
        // empty string first
        
        inbuf[0] = '\0';
        
        // keep reading till we get a  line with some interesting
        // data on
        
        do {
                
                fgets(inbuf, 1023, instream);
                
                // cut off leading spaces
                
                {
                        char *i = inbuf;
                        while(isspace(*i)) ++i;
                        strcpy(inbuf, i);
                }
                
                // remove comments
                
                {
                        char *i = strchr(inbuf, '#');
                        if(i)
                                *i = '\0';
                }
                
                // cut off ending spaces
                
                {
                        char *i = inbuf + strlen(inbuf) - 1;
                        while(isspace(*i)) --i;
                        *(i+1) = '\0';
                }
                
        } while(!feof(instream) && !inbuf[0]);
        
        if(feof(instream))
                return NULL;
        
        return inbuf;
}

static void parse_machine(cluster_t *cluster, char *name, char *type)
{
        // a lab machine
        
        // create new machine_t structure
        
        machine_t *machine = malloc(sizeof(*machine));
        
        machine->hostname = strdup(name);
        machine->type = 
                !strcasecmp(type, "win") ? MACHINE_WIN : 
                  !strcasecmp(type, "unix") ? MACHINE_UNIX :
                    !strcasecmp(type, "linux") ? MACHINE_LINUX :
                      MACHINE_CHECKUP;
                          
        machine->num_users = 0;
        machine->users = NULL;			 
        machine->status = STATUS_UP;   // assume up 
	machine->interface_data = ui_new_interface_data(machine);
        
        // increase global list size
        
        if(machines)
                machines = realloc(machines,
                                   (num_machines + 1) *
                                   sizeof(*machines));
        else
                machines = malloc(sizeof(*machines));
        
        // add to global list
        
        machines[num_machines++] = machine;
        
        // increase cluster list size 
        
        if(cluster->machines)
                cluster->machines
                        = realloc(cluster->machines,
                                  (cluster->num_machines + 1)
                                  * sizeof(*cluster->machines));
        else
                cluster->machines
                        = malloc(sizeof(*cluster->machines));
        
        // add to cluster
        
        cluster->machines[cluster->num_machines++] = machine;
}

static cluster_t *read_cluster(FILE *file)
{
        // create new cluster structure
        
        cluster_t *cluster = malloc(sizeof(*cluster));
        
        cluster->name = "Unnamed Cluster";
        cluster->machines = NULL;
        cluster->num_machines = 0;
        
        // read from file
        
        while(!feof(file)) {
                char *line = read_line(file);
                
                // end of read
                
                if(!strcmp(line, "}"))
                        return cluster;
                else {
                        
                        // extract first token
                        
                        char *token_name = strtok(line, " \t");
                        
                        // extract value... hmm
                        
                        char *value = token_name + strlen(token_name) + 1;
                        
                        while(isspace(*value))
                                value++;
                        
                        // decide what to do
                        
                        if(!strcasecmp(token_name, "ClusterName")) {
                                cluster->name = strdup(value);
                        } else {
                                // a machine
                                parse_machine(cluster,
                                              token_name,
                                              value);
                        }
                }
        }
        
        fprintf(stderr, "Error reading cluster\n");
        
        return NULL;
}

void read_machines(char *machines_file)
{
        FILE *file;
        
        file = fopen(machines_file, "r");
        
        if(!file) {
                fprintf(stderr, 
                        "read_machines: cannot open %s\n", 
                        machines_file);
                exit(-1);
        }
        
        // create initial clusters list
        
        num_clusters = 0;
        clusters = NULL;
        
        // and machines list
        
        num_machines = 0;
        machines = NULL;
        
        // read from file
        
        while(!feof(file)) {
                char *line = read_line(file);
          
                if(!line)
                        break;
                
                // start of cluster definition
                
                if(!strcmp(line, "{")) {
                        cluster_t *newcluster = read_cluster(file);
                        
                        if(clusters)
                                clusters = realloc(clusters,
                                                   (num_clusters + 1) * sizeof(*clusters));
                        else
                                clusters = malloc(sizeof(*clusters));
                        
                        clusters[num_clusters++] = newcluster;

                } else {
                        
                        // error:
                        
                        fprintf(stderr, "read_machines: [%s], wtf?\n", line);
                }
        }
        
        fclose(file);
}

static void print_cluster(cluster_t *cluster)
{
        int m;
     
        printf("%s: %i machines\n",
               cluster->name,
               cluster->num_machines);
        
        for(m=0; m<cluster->num_machines; m++) {
                
                machine_t *machine = cluster->machines[m];
                
                printf("\t%s     \t%s\n",
                       machine->hostname,
                       machine->type == MACHINE_WIN ? "NT" : "Unix");
        }
}

static void print_clusters() 
{
        int c;

        for(c=0; c<num_clusters; c++) {
                print_cluster(clusters[c]);
        }
}
