###############################################################################
#!/usr/local/bin/perl
# 
# $Header: UpdateHeaderUtil.pl 09-feb-2005.03:42:51 gsbhatia Exp $
#
# UpdateHeaderUtil.pl
# 
# Copyright (c) 2005, Oracle. All rights reserved.  
#
#    NAME
#      UpdateHeaderUtil.pl - <one-line expansion of the name>
#
#    DESCRIPTION
#      <short description of component this file declares/defines>
#
#    NOTES
#      <other useful comments, qualifications, etc.>
#
#    MODIFIED   (MM/DD/YY)
#    gsbhatia    02/08/05 - Adding support for .plb 
#    gsbhatia    02/07/05 - gsbhatia_repmgr_1
#    gsbhatia    02/07/05 - Creation
# 
#
# UpdateHeaderUtil.pl - tools to mass update RepManager Header
# Note - This util expects that headers have already been inserted using
# HeaderUtil.pl
# It will scan previous RepMgr sql hierarchy and infer the appropriate
# sequence nos. and params
# Usage: $ADE_VIEW_ROOT/emcore/sysman/admin/emdrep/bin/UpdateHeaderUtil.pl
# <path> = absolute path of the directory containing sql files
#
# Notes:
# - It must be run within a view with an open transaction
# - It tries to resolve sequencing of sql files by scanning existing RepMgr sqls
# - It does not check in your changed files, you must run ade ci or ade ciall to check in the changes.
###############################################################################


use Carp;

use lib "$ENV{'ADE_VIEW_ROOT'}/emcore/scripts/install";
use lib "$ENV{'ADE_VIEW_ROOT'}/emcore/sysman/admin/emdrep/bin";

use SQLFile;

my $SQL_HOME = "$ENV{'ADE_VIEW_ROOT'}/emcore/sysman/admin/emdrep/sql";

my %DEFINED_TYPES = (
                     'types'=>1,
                     'tables'=>1,
                     'indexes'=>1,
                     'procs'=>1, 
                     'funcs'=>1,
                     'triggers'=>1,
                     'views'=>1, 
                     'pkgdefs'=>1,
                     'pkgbodys'=>1,
                     'type_bodys'=>1,
                     'synonyms'=>1, 
                     'post_creation'=>1,
                     'out_of_box'=>1, 
                     'schema_upgrade'=>1,
                     'data_upgrade'=>1, 
                     'schema_downgrade'=>1,
                     'data_downgrade'=>1
                     );

my %DEFINED_VERS = (
                    'v10102' => '10.1.0.3',
                    'v101040' => '10.1.0.4',
                    'v102010' => '10.2.0.1'
                    );

my %map;

$AVN = $ENV{'ADE_VIEW_NAME'};
die "not in view!!" if(!defined $AVN);

initMap();
create("$SQL_HOME/core/latest/core_cre.sql");

sub initMap{
  for $key (keys %DEFINED_TYPES){
    $map{$key} = 0;
  }
}


sub create{
  my ($file, @paramList) = @_;
  my $sql = new SQLFile;
  $sql->setPath($file);
  $sql->setType($sql->guessType);
  if ($sql->isValid){
    #update the header
    updateHeader($sql, @paramList);
  }
  #process the file for contained sqls    
  if(open(FIN,$file)){
    my @lines = <FIN>;    
    close(FIN);
    for (@lines){
      if (!/\s*[rR][eE][mM]/){
        if (/\s*(@&{1,2}EM_SQL_ROOT\/.*\.sql)\s*(.*)$/){
          &create(canonicalizeFilename($1), makeParamList($2));  
        }        
      }
    }
  }
}


sub canonicalizeFilename{
  my $str = shift;
  $str =~ s/@&{1,2}EM_SQL_ROOT/$SQL_HOME/;
  return $str;
}

sub makeParamList{
  my $paramStr = shift;
  my @paramList = split(/\s+/, $paramStr);
  my $counter=0;
  for (@paramList){
    die "Invalid param: $_" if (!isValidParam($_));
    splice(@paramList, $counter, 1, substr($_, 1));
    $counter++;
  }
  return @paramList;
}

sub trimLine
{
  my $string = shift;
  $string =~ s/^\s+//;
  $string =~ s/\s+$//;
  return $string;
}

sub isValidParam{
  my $param = shift; 
  if ($param !~ m/&{1,2}(?:EM_SQL_ROOT|EM_REPOS_USER|EM_REPOS_PWD|
                         EM_REPOS_MODE|EM_TEMP_TABLESPACE_NAME|EM_TABLESPACE_NAME|
                         EM_DEFAULT_DATAFILE_NAME|EM_DEFAULT_DATAFILE_INIT_SIZE|
                         EM_DEFAULT_DATAFILE_EXTEND_SIZE|EM_ECM_DEPOT_TABLESPACE|
                         EM_ECM_DATAFILE_NAME|EM_ECM_DATAFILE_INIT_SIZE|
                         EM_ECM_DATAFILE_EXTEND_SIZE|EM_ECHO_SQL)/x){
    return 0;
  }
  return 1;    
}

sub updateHeader{
  my ($sql, @paramList) = @_;

  #my $p = $sql->getPath;
  #$p =~ s/.*emdrep/@\.\./;
  #print "$p\n";

  my $params;
  for (@paramList){
    $params .=","."$_";
  }

  $params = substr($params, 1); 
  $path = $sql->getPath;
  #print "Updating header file for $path\n";
  #print "executing ade co -c \"updating repmgr header\" $path\n";
  system "ade co -c \"updating repmgr header\" $path";

  my $file = $sql->getPath;
  if(open(FIN,$file))
  {
    my @lines = <FIN>;    
    close(FIN);

    my $type = $sql->getType;
    my $ver = $sql->getVersion;

    #remove existing "Rem drv:" line
    my $counter=0;
    for (@lines){
      if (/[rR][eE][mM]\s+[dD][rR][vV]\s*:/){
        splice(@lines, $counter, 1);
        last;
      }
      $counter++;
    }
    if(open(FOUT,">$file"))
    {
      if($type eq 'data_upgrade' || $type eq 'schema_upgrade')
      {
        #TODO
        #print FOUT "Rem drv: <migrate type=\"$type\" version=\"$ver\"/> \n";
      }else
      {
        my $type = $sql->getType;
        if ($params eq ""){
          print FOUT "Rem drv: <create type=\"$type\" seq=\"$map{$type}\"/>\n";
        }else{
          print FOUT "Rem drv: <create type=\"$type\" seq=\"$map{$type}\" params=\"$params\"/>\n";
        }
        $map{$sql->getType}++;
      }
      foreach $h (@lines)
      {
        print FOUT $h;
      }
      close(FOUT);
    }
  }
}
