//serverinfo.c:

/*
 *      Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2009-2014
 *
 *  This file is part of RoarAudio PlayList Daemon,
 *  a playlist management daemon for RoarAudio.
 *  See README for details.
 *
 *  This file is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License version 3
 *  as published by the Free Software Foundation.
 *
 *  RoarAudio 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 software; see the file COPYING.  If not, write to
 *  the Free Software Foundation, 51 Franklin Street, Fifth Floor,
 *  Boston, MA 02110-1301, USA.
 *
 */

#include "rpld.h"

static struct roar_server_info * __info_lib = NULL;
static struct roar_server_info * __info_server = NULL;

static struct roar_server_info * rpld_serverinfo_get_raw(int reinit) {
 static struct roar_server_info info;
 static int inited = 0;

 if ( reinit || !inited ) {
  memset(&info, 0, sizeof(info));
  inited = 1;
  rpld_serverinfo_update(RPLD_SERVERINFO_SOURCE_BUILDIN, NULL);
  rpld_serverinfo_update(RPLD_SERVERINFO_SOURCE_LIBRARY, NULL);
 }

 return &info;
}

int rpld_serverinfo_free(void) {
 roar_server_info_free(__info_lib);
 roar_server_info_free(__info_server);
 __info_lib = NULL;
 __info_server = NULL;

 rpld_serverinfo_get_raw(1);

 return 0;
}

const struct roar_server_info * rpld_serverinfo_get(void) {
 return rpld_serverinfo_get_raw(0);
}

static int rpld_serverinfo_update_lib(struct roar_server_info * info) {
 if ( __info_lib != NULL )
  return 0; // noop.

 __info_lib = roar_library_info();
 if ( __info_lib == NULL )
  return -1;

#define _copy(var) if ( __info_lib->var != NULL ) info->var = __info_lib->var
 _copy(location);
 _copy(contact);
 _copy(serial);
 _copy(address);
 _copy(hostid);
 _copy(un.sysname);
 _copy(un.release);
 _copy(un.nodename);
 _copy(un.machine);
#undef _copy

 return -1;
}

static int rpld_serverinfo_update_server(struct roar_server_info * info, const char * server) {
 struct rpld_backend * backend;

 if ( __info_server != NULL )
  return 0; // noop.

 backend = backend_get_connection(server);
 if ( backend == NULL )
  return -1;

 if ( !(backend->flags & BACKEND_FLAG_CONNECTED) ) {
  roar_err_set(ROAR_ERROR_NOTCONN);
  return -1;
 }

 __info_server = roar_server_info(&(backend->con));
 backend_unref(backend);
 if ( __info_server == NULL )
  return -1;

#define _copy(var) if ( __info_server->var != NULL ) info->var = __info_server->var
 _copy(location);
 _copy(description);
 _copy(contact);
 _copy(serial);
 _copy(uiurl);
#undef _copy

 return -1;
}

static int rpld_serverinfo_update_object(struct roar_server_info * info, const struct roar_server_info * obj) {
 if ( obj == NULL ) {
  roar_err_set(ROAR_ERROR_FAULT);
  return -1;
 }

#define _copy(var) if ( obj->var != NULL ) info->var = obj->var
 _copy(location);
 _copy(description);
 _copy(contact);
 _copy(serial);
 _copy(address);
 _copy(uiurl);
#undef _copy

 return 0;
}

int rpld_serverinfo_update(enum rpld_serverinfo_source source, const void * argp) {
 struct roar_server_info * info = rpld_serverinfo_get_raw(0);

 switch (source) {
  case RPLD_SERVERINFO_SOURCE_BUILDIN:
    // the following if is optimized out by compiler.
    if ( DISTRIBUTION_VERSION_STRING[0] == 0 ) {
     info->version = "rpld/" VERSION " " ROAR_VSTR_ROARAUDIO;
    } else {
     info->version = "rpld/" VERSION " " ROAR_VSTR_ROARAUDIO " (" DISTRIBUTION_VERSION_STRING ")";
    }
    info->license = ROAR_LICENSE_GPLv3_0;
    info->build = BUILD_STAMP;
    return 0;
   break;
  case RPLD_SERVERINFO_SOURCE_LIBRARY:
    return rpld_serverinfo_update_lib(info);
   break;
  case RPLD_SERVERINFO_SOURCE_SERVER:
    return rpld_serverinfo_update_server(info, argp);
   break;
  case RPLD_SERVERINFO_SOURCE_OBJECT:
    return rpld_serverinfo_update_object(info, argp);
   break;
 }

 roar_err_set(ROAR_ERROR_NOTSUP);
 return -1;
}

//ll
