#!/usr/bin/perl
use 5.030 ; use strict ; use warnings ; 
use Getopt::Std ;
use Getopt::Long qw [ GetOptions :config bundling no_ignore_case pass_through ] ; # GetOptionsFromArray ] ;
use Time::HiRes qw[ gettimeofday tv_interval sleep ] ; # Perl 5.7.3からコアモジュール
use Term::ANSIColor qw[ color :constants ] ; $Term::ANSIColor::AUTORESET = 1 ;
use FindBin qw[ $Script $Bin ] ; 
use lib "$FindBin::Bin/lib" ; 
use App::ggdrv::start ; # GCPでAPIを設定する方法を、読む人に説明する文書を表示する。
use App::ggdrv::crecord ; # 設定ファイルの書き込み方を説明する。自動実行の機能も提供。
use App::ggdrv::tokens  ; # トークン2個を設定する。表示も可能。
use App::ggdrv::fsearch ; 
use App::ggdrv::fsearchall ; 
use App::ggdrv::upload ;
use App::ggdrv::update ;
use App::ggdrv::download ;
use App::ggdrv::upload5 ; # uploadに依存
use App::ggdrv::download5 ;
use App::ggdrv::sync5 ; # update に依存
## 計算秒数などについての処理
#my %o ; 
our $prt2 ;  # 最後に2次情報を出さないなら 0 という値が設定される。
my $time_start = [ gettimeofday ] ; 
END{ ## 終了する段階で、二次情報を表示する
  exit if 0 eq ($prt2//'') ;# 0 eq  ( $o{2} // '' ) ;
  use POSIX qw [ strftime ] ; 
  my $dt1000 = sub { my $t = [ gettimeofday ] ; strftime( "%Y-%m-%d %H:%M:%S." . sprintf("%03d", $t->[1] / 1e3 ) , localtime( $t->[0] ) ) } ;
  my $sec = sprintf "PT %0.3f S", tv_interval ( $time_start ) ; 
  my $env_ga = $ENV{GGDRV_API} // 'undef' ; 
  say STDERR  BOLD YELLOW FAINT "-- " , $dt1000->() , "  calculation time: ", $sec,  "  ( $Script ; \$\$==$$ ; \$GGDRV_API==$env_ga )"; 
}

## 主要部はここから。

my $a1 = shift @ARGV or do { $prt2 = 0 ; & App::ggdrv::start::start() ; exit } ;
GetOptions ( '2=s' => \$prt2 ) ;
GetOptions ( run => \my$run ) ; 
GetOptions ( tokens => \my$tokens , get => \my$get , try => \my$try , atoken => \my$atoken ) ; 
for ( $a1 ) { 
  /^crecord$/ and & App::ggdrv::crecord::crecord( $run ) and $prt2 = 0 ; 
  /^(tokens|token)$/ and & App::ggdrv::tokens::tokens( $get , $try , $atoken ) ;
  /^fsearch$/ and & App::ggdrv::fsearch::fsearch () ; 
  /^fsearchall$/ and & App::ggdrv::fsearchall::fsearchall () ;
  /^upload$/ and & App::ggdrv::upload::upload () ; 
  /^update$/ and & App::ggdrv::update::update () ;
  /^download$/ and & App::ggdrv::download::download ()  ;
  /^upload5$/ and & App::ggdrv::upload5::upload5 () ;  ## ここから5列TSVファイルを使った操作3種類
  /^download5$/ and & App::ggdrv::download5::download5 () ;
  /^sync5$/ and & App::ggdrv::sync5::sync5 () ;
  /^--help$/ and do { $prt2=0 ; & HELP_MESSAGE } ;
}
exit ;

## ヘルプの扱い
sub VERSION_MESSAGE {}
sub HELP_MESSAGE{
    use FindBin qw[ $Script ] ; 
    $ARGV[1] //= '' ;
    open my $FH , '<' , $0 ;
    while(<$FH>){
        s/\$0/$Script/g ;
        print $_ if $ARGV[1] eq 'opt' ? m/^\ +\-/ : s/^=head1// .. s/^=cut// ;
    }
    close $FH ;
    exit 0 ;
}

# 数を3桁区切りに変換する。
sub d3 ($) { $_[0] =~ s/(?<=\d)(?=(\d\d\d)+($|\D))/,/gr } ; 

=encoding utf8 

=head1

 ggdrv 

  サブコマンド方式で、様々な関連する機能を実行可能としている。
  OAuthの仕組みでGoogleドライブにファイルを自動更新で同期する機能を提供する。

 利用例 :

   ggdrv --help  # --help により、このヘルプの文面が現れる。

  [設定系]
   ggdrv   # 引数無しで実行すると、最初のセットアップの仕方(ブラウザ越しで「クライアントシークレット」を作る方法)が表示される。
   ggdrv crecord  # クライアントシークレット(Client)などを、設定ファイルに書き込む方法が表示される。
   ggdrv crecord --run  # 表示される内容を実際に実行する。
   ggdrv tokens  #  トークンの情報2個を単に表示する。(リフレッシュトークン(使わないと半年で無効化)とアクセストークンがある。)
   ggdrv tokens --get   # トークンを取得する(設定ファイルに書き込む)。書き込む前のファイルはバックアップは1回のみ保管。
   ggdrv tokens --get --try   # トークンを取得するが、設定ファイルには書き込まない。
   ggdrv tokens --atoken  # アクセストークンのみ更新する。60分未使用であれば、更新は必要。-try を指定すると設定ファイルに書き込まない。

  [ファイル検索]
   ggdrv fsearch FILENAME # ファイルを最大100個まで探す(フォルダは指定不能)。ワイルドカードを指定可能。タブ区切り5列で出力。
   ggdrv fsearchall -g10  # ファイルを100個ずつ -g で指定した回数出力(フォルダは指定不能)。1個のファイルにつき、縦に4行を出力。## <-- 時々リフレッシュトークンを更新する必要あり。

  [(単純な)アップロード/更新/ダウンロード]
   ggdrv upload -f フォルダID(28文字) FILE [FILE] .. # アップロードする。 同名ファイルに対し複数回実行したら、その分グーグルドライブ上に現れるので注意。
   ggdrv update ID1 FILE1 [ID2 FILE2] [ID3 FILE3] .. # 更新する。33文字のIDに対して、ローカルのファイルの名前をペアにして指定。
   ggdrv download ファイルID(33文字) ローカルで予定するファイル名 # ダウンロードする。

  [作業対象のファイルを管理しつつアップロード/更新/ダウンロード] ※ サブコマンドに「5」が後置するのが特徴。
   ggdrv upload5 FOLDER_ID LOCAL_DIR > VAR_FILE # アップロードする。標準出力をファイルに保管して、続くサブコマンドでも使う。
   ggdrv download5 LOCAL_DIR < VAR_FILE        # ダウンロードする。
   ggdrv sync5 OLD_DIR NEW_DIR < VAR_FILE   # 同期に使う。OLD_DIRはGoogleドライブと予め同期させ、NEW_DIRと違えば、それをアップデート。

 オプション: 
   -2 0 : 最後に2次情報を標準エラー出力に出さない。サブコマンドの後ろに置くこと。

 環境変数 : export VAR=VALUE で指定。unset VAR で解除が可能。

   GGDRV_API    :  クライアントIDやクライアントシークレットを保管するファイルの名前。未指定なら ~/ggdrv2303v1 である。


下野寿之 Toshiyuki SHIMONO <bin4tsv@gmail.com>

Copyright (c) 2023 Toshiyuki SHIMONO. All rights reserved.
This program is free software; you can redistribute it and/or
modify it under the same terms as Perl itself.

=cut 
