#!/usr/bin/perl
######################################################################
#
# gate1_log_correction.pl
# gate1의 잘못된 명령어 로그의 날짜를 수정한다.
#
# 로그 예) 1602623392:#:20201014060909-T0690081-192.168.7.113-172.16.7.106-3588.10085354:#:17:#:AAAD:#:T0690081:#:홍길동:#:192.168.7.113:#::#:UNPP:#::#:YNCC:#:njuu01:#:172.16.7.106:#:운영서버:#::#:운영서버:#:ssh:#:501:#:wassvr
# 파일명 예) 20200925-172.16.7.235
#
######################################################################
use warnings;
use strict;
use POSIX qw(strftime);

######################################################################
#
# 로그 시간의 오차를 명시한다. (초단위)
#
######################################################################
my $fn_date = "";
my $ARGC = @ARGV;
if ($ARGC < 2) {
    printf("Usage: $0 <log file> <output dir> <Correction Value(Second)>\n\n");
    printf("    ex) $0 20201030-192.168.21.235 /work/output 10458232\n");
    printf("    ex) $0 20201008-192.168.21.235 /test/logs 172858\n");
    exit;
}

my $output_dir = $ARGV[1];
#my $time_rate = 10458232;  # SEOUL
#my $time_rate = 172858 ;   # YEOSU
my $time_rate = $ARGV[2];

######################################################################
#
# 로그의 한줄을 읽어서 시간을 수정한 뒤 수정된 값을 반환한다.
#
######################################################################
sub conv_date {
    my $log_str1 = $_[0];
    my $epoch1 = 0;
    my $epoch2 = 0;
    my $date_str1 = "";
    my $date_str2 = "";
    my $regex = qr/^([0-9]*):#:([0-9]*)-(.*)/mp;

    if ( $log_str1 =~ /$regex/g ) {
      $epoch1 = $1 + 0;
      $date_str1 = $2;
    }

    $epoch2 = $epoch1 + $time_rate;
    $date_str2 = strftime "%Y%m%d%H%M%S", localtime($epoch2);
    if (length($fn_date) == 0) {
        $fn_date = strftime "%Y%m%d", localtime($epoch2);
        #printf("[DEBUG]***fn_date:%s\n", $fn_date);
    }

    $log_str1 =~ s/$epoch1/$epoch2/;
    $log_str1 =~ s/$date_str1/$date_str2/;

    #printf("[DEBUG]epoch1:%u\n", $epoch1);
    #printf("[DEBUG]epoch2:%u\n", $epoch2);
    #printf("[DEBUG]date_str2:%s\n", $date_str2);

    return($log_str1);
}

######################################################################
#
# 출력 파일명을 만든다.
#
######################################################################
sub get_out_filename {
    my $str_line1 = $_[0];
    my $str_line2 = $_[1];
    my $ret_str = "";
    my $regex = qr/^([0-9]*)-(.*)/mp;

    if ( $str_line1 =~ /$regex/g ) {
        $ret_str = $str_line2."-".$2;
    }

    return($ret_str);
}

printf("[DEBUG]ARGV[0]:%s\n", $ARGV[0]);
my $linestr = "";

######################################################################
#
# 로그에서 한줄만 읽어서 출력 파일명에 사용할 날짜를 얻는다.
#
######################################################################
open (IN_FILE, '<', $ARGV[0]) or die "Failed to open. $!";
while (<IN_FILE>) {
    $linestr = $_;
    chomp($linestr);    # $linestr값이 저장되어 있는데 거기서 끝의 공백을 지워준다.
    $linestr = &conv_date($linestr);
    #printf("[DEBUG]%s\n", $linestr);
    if (length($fn_date) > 0) {
        last;
    }
}
close(IN_FILE) or die "Failed to close. $!";

######################################################################
#
# 출력 디렉토리를 만들고 출력 파일명을 완성한다.
#
######################################################################
my $out_file = $output_dir."/".&get_out_filename($ARGV[0], $fn_date);
printf("[DEBUG]out_file:%s\n", $out_file);

######################################################################
#
# 변환 !!
#
######################################################################
open (IN_FILE, '<', $ARGV[0]) or die "Failed to open. $! ";
open (OUT_FILE, '>', $out_file) or die "Failed to open. $! ";
while (<IN_FILE>) {
    $linestr = $_;
    chomp($linestr);    # $linestr값이 저장되어 있는데 거기서 끝의 공백을 지워준다.
    $linestr = &conv_date($linestr);
    print OUT_FILE "$linestr\n";
}
close(IN_FILE) or die "Failed to close. $!";
close(OUT_FILE) or die "Failed to close. $!";

exit;