#!@PERL_EXECUTABLE@ -w
#
# ==========================================================================
#
# Zone Minder Configuration Script, $Date$, $Revision$
# Copyright (C) 2001-2008  Philip Coombes
#
# 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#
# ==========================================================================
#
# This script is used to generate initial config headers and database data.
#

use strict;
use lib '@CMAKE_CURRENT_BINARY_DIR@/scripts/ZoneMinder/lib';
use ZoneMinder::ConfigData qw/:data/;

$| = 1;

my $config_header = '@CMAKE_BINARY_DIR@/zm_config_defines.h';
my $config_sql = '@CMAKE_CURRENT_BINARY_DIR@/db/zm_create.sql';

generateConfigFiles();

exit;

sub generateConfigFiles
{
	generateConfigHeader();
	generateConfigSQL();
}

sub generateConfigHeader {
	print("Generating '$config_header'\n");
	open(CFG_HDR_FILE, '>'.$config_header) or die("Can't open '$config_header' for writing");
	print(CFG_HDR_FILE "// The file is autogenerated by zmconfgen.pl\n");
	print(CFG_HDR_FILE "// Do not edit this file as any changes will be overwritten\n\n");
	my $last_id = 0;
	my $define_list = '';
	my $declare_list = '';
	my $assign_list = '';
	foreach my $option ( @options ) {
		next if !defined($option->{id});

    # If only used in ui, then don't include it in C++ config defines
    next if $option->{processes} and ($option->{processes} ne 'web');

    my $opt_id = $option->{id};
    my $opt_name = $option->{name};
    my $opt_type = $option->{type};
    my $var_name = substr( lc($opt_name), 3 );

    $define_list .= "#define $opt_name $opt_id\n";

    $declare_list .= "\t";
    if ( $opt_type->{db_type} eq 'boolean' ) {
      $declare_list .= 'bool ';
    } elsif ( $opt_type->{db_type} eq 'integer' || $opt_type->{db_type} eq 'hexadecimal' ) {
      $declare_list .= 'int ';
    } elsif ( $opt_type->{db_type} eq 'decimal' ) {
      $declare_list .= 'double ';
    } else {
      $declare_list .= 'const char *';
    }
    $declare_list .= $var_name.";\\\n";

    $assign_list .= "\t";
    $assign_list .= $var_name.' = ';
    if ( $opt_type->{db_type} eq 'boolean' ) {
      $assign_list .= '(bool)';
    } elsif ( $opt_type->{db_type} eq 'integer' || $opt_type->{db_type} eq 'hexadecimal' ) {
      $assign_list .= '(int)';
    } elsif ( $opt_type->{db_type} eq 'decimal' ) {
      $assign_list .= '(double) ';
    } else {
      $assign_list .= '(const char *)';
    }
    $assign_list .= 'config.Item('.$opt_name.");\\\n";

    $last_id = $option->{id};
  } # end foreach option
  print( CFG_HDR_FILE $define_list."\n\n" );
  print( CFG_HDR_FILE "#define ZM_MAX_CFG_ID $last_id\n\n" );
  print( CFG_HDR_FILE "#define ZM_CFG_DECLARE_LIST \\\n" );
  print( CFG_HDR_FILE $declare_list."\n\n" );
  print( CFG_HDR_FILE "#define ZM_CFG_ASSIGN_LIST \\\n" );
  print( CFG_HDR_FILE $assign_list."\n\n" );
  close( CFG_HDR_FILE );
}

sub generateConfigSQL {
  print("Updating '$config_sql'\n");
  my $config_sql_temp = $config_sql.'.temp';
  open(CFG_SQL_FILE, '<'.$config_sql) or die("Can't open '$config_sql' for reading");
  open(CFG_TEMP_SQL_FILE, '>'.$config_sql_temp) or die("Can't open '$config_sql_temp' for writing");
  while ( my $line = <CFG_SQL_FILE> ) {
    last if ( $line =~ /^-- This section is autogenerated/ );
    print(CFG_TEMP_SQL_FILE $line);
  }
  close(CFG_SQL_FILE);

  print( CFG_TEMP_SQL_FILE "-- This section is autogenerated by zmconfgen.pl\n" );
  print( CFG_TEMP_SQL_FILE "-- Do not edit this file as any changes will be overwritten\n" );
  print( CFG_TEMP_SQL_FILE "--\n\n" );
  print( CFG_TEMP_SQL_FILE "delete from Config;\n\n" );
  foreach my $option ( @options ) {
    #print( $option->{name}."\n" ) if ( !$option->{category} );
    $option->{db_type} = $option->{type}->{db_type};
    $option->{db_hint} = $option->{type}->{hint};
    $option->{db_pattern} = $option->{type}->{pattern};
    $option->{db_format} = $option->{type}->{format};
    my %processes = map { $_ => $_ } split(',', $option->{processes}) if $option->{processes};
    if ( $option->{db_type} eq 'boolean' ) {
      $option->{db_value} = ($option->{value} eq 'yes') ? '1' : '0';
    } else {
      $option->{db_value} = $option->{value};
    }
    if ( $option->{name} eq 'ZM_DYN_CURR_VERSION' || $option->{name} eq 'ZM_DYN_DB_VERSION' ) {
      $option->{db_value} = '@VERSION@';
    }
    if ( my $requires = $option->{requires} ) {
      $option->{db_requires} = join(';', map { my $value = $_->{value}; $value = ($value eq 'yes')?1:0 if ( $options_hash{$_->{name}}->{db_type} eq 'boolean' ); ( "$_->{name}=$value" ) } @$requires );
    } else {
      $option->{db_requires} = '';
    }
    printf( CFG_TEMP_SQL_FILE
      "INSERT INTO Config SET Id = %d, Name = '%s', Value = '%s', Type = '%s', DefaultValue = '%s', Hint = '%s', Pattern = '%s', Format = '%s', Prompt = '%s', Help = '%s', Category = '%s', Readonly = '%s', Requires = '%s';\n",
      $option->{id},
      $option->{name},
      addSlashes($option->{db_value}),
      $option->{db_type},
      addSlashes($option->{default}),
      addSlashes($option->{db_hint}),
      addSlashes($option->{db_pattern}),
      addSlashes($option->{db_format}),
      addSlashes($option->{description}),
      addSlashes($option->{help}),
      $option->{category},
      $option->{readonly}?1:0,
      $option->{db_requires}
    );
  } # end foreach option
  print(CFG_TEMP_SQL_FILE "\n");
  close(CFG_TEMP_SQL_FILE);

  rename( $config_sql_temp, $config_sql ) or die( "Can't rename '$config_sql_temp' to '$config_sql': $!" );
}

sub addSlashes {
  my $string = shift;
  return '' if !defined($string);
  $string =~ s|(['"])|\\$1|g;
  return $string;
}