/*
 * @(#)snapshot.java
 *
 * Copyright 2001 Nomura Research Institute, LTD. All rights reserved.
 *
 * RID-X : スナップショット
 *
 * @author  Intelligent Technology Inc.
 * @version 1.01 2002/01/31
 */
package jp.co.nri.rid.snapshot;

import java.io.File;
import java.util.Date;
import java.lang.Math;
import java.text.DateFormat;
import java.text.SimpleDateFormat;

import jp.co.iti.fagot.ZApp;
import jp.co.iti.fagot.doc.DocDocument;
import jp.co.iti.fagot.doc.DocManager;
import jp.co.iti.fagot.util.ZDebug;
import jp.co.iti.fagot.util.ZResource;
import jp.co.iti.fagot.util.ZProperties;
import jp.co.iti.fagot.util.ZString;

import jp.co.nri.rid.mapper.HtmlMapper;

/**
 * スナップショット
 */
public class snapshot {

    /** rid.work.dirプロパティ  **/
    final static public String RID_WORK_DIR     = "rid.work.dir";
    /** rid.admin.dirプロパティ  **/
    final static public String RID_ADMIN_DIR    = "rid.admin.dir";
    /** rid.team.dirプロパティ  **/
    final static public String RID_TEAM_DIR     = "rid.team.dir";
    /** rid.public.dirプロパティ  **/
    final static public String RID_PUBLIC_DIR   = "rid.public.dir";
    /** rid.snapshot.dirプロパティ  **/
    final static public String RID_SNAPSHOT_DIR = "rid.snapshot.dir";
    /** snapshot.bgcolorプロパティ  **/
    final static public String SNAPSHOT_BGCOLOR = "snapshot.bgcolor";

    /** Workディレクトリ                  **/
    protected String pr_workDir;
    /** Adminディレクトリ                 **/
    protected String pr_adminDir;
    /** 製作指示書ディレクトリ            **/
    protected String pr_teamDir;
    /** 紙芝居ディレクトリ                **/
    protected String pr_publicDir;
    /** スナップショットディレクトリ      **/
    protected String pr_snapshotDir;
    /** スナップショット背景色            **/
    protected String pr_bgColor;
    /** 生成スナップショットディレクトリ  **/
    protected String pr_snapshotDestDir;

    /** ナビバーＨＴＭＬファイル名(_navi.html)  **/
    static final String pr_naviHtml = "_navi.html";
    /** ナビバーＨＴＭＬファイル名(_navi.htm)   **/
    static final String pr_naviHtm  = "_navi.htm";
    /** デフォルトバックグラウンド              **/
    static final String pr_gray     = "#808080";

  /**
   * デフォルトコンストラクタ
   */
  public snapshot() {
      pr_adminDir = "";
      pr_teamDir = ""; 
      pr_publicDir = "";
      pr_snapshotDir = "";
      pr_bgColor = "";
      pr_snapshotDestDir = "";
  }

/**
  * スナップショット実行
  *
  * @param  String      szPjDir         プロジェクトＤＩＲ
  * @param  String      time_stamp      タイムスタンプ（新規作成するディレクトリ名）
  * @return boolean     true(成功) / false (失敗)
  */
    public boolean exec(String szPjDir, String time_stamp) throws Exception {

        boolean ret = false;

        // リソースからディレクトリ群の取得
        ZResource res  = ZApp.getTheApp().getResource();
        pr_workDir     = szPjDir + File.separator + res.getString(RID_WORK_DIR);
        pr_adminDir    = szPjDir + File.separator + res.getString(RID_ADMIN_DIR);
        pr_teamDir     = szPjDir + File.separator + res.getString(RID_TEAM_DIR); 
        pr_publicDir   = szPjDir + File.separator + res.getString(RID_PUBLIC_DIR);
        pr_snapshotDir = szPjDir + File.separator + res.getString(RID_SNAPSHOT_DIR); 
        pr_bgColor     = res.getString(SNAPSHOT_BGCOLOR); 
    
        // コピー先のディレクトリにタイムスタンプのディレクトリを生成
        pr_snapshotDestDir = time_stamp;
        xcopy xc = new xcopy();
        xc.makeDir(pr_snapshotDir + File.separator + pr_snapshotDestDir);

        // WORKディレクトリからをコピー
        String newWorkDir = pr_snapshotDir + File.separator + pr_snapshotDestDir + File.separator + res.getString(RID_WORK_DIR);
        ret = directory(pr_workDir, newWorkDir);

        return ret;
    }

/**
  * ディレクトリのコピー
  *
  * @param  String      source          移動元ディレクトリ名
  * @param  String      destination     移動先ディレクトリ名
  *
  * @return boolean     true(成功) / false (失敗)
  */
    private boolean directory(String source, String destination) throws Exception {

        boolean ret = false;
        xcopy xc = new xcopy();
        File source_file = new File(source);
        File destination_file = new File(destination);

        // ディレクトリの有無
        ret = source_file.exists();
        if (ret){
            //ディレクトリの生成／日付変更
            ret = xc.makeDir(destination);
            if (ret) destination_file.setLastModified(source_file.lastModified());

            // ファイルおよびディレクトリのリストを取得
            String[] source_lst =  source_file.list();

            //ファイルまたはサブディレクトリを削除
            for (int n = 0; n < source_lst.length; n++) {
                ret = movement(source,  destination, source_lst[n]);
            }
        }
        return ret;
    }


/**
  * ディレクトリ／ファイルで分岐
  *
  * @param  String      source          移動元ディレクトリ名
  * @param  String      destination     移動先ディレクトリ名
  * @param  String      filename        ファイル名
  *
  * @return boolean     true(成功) / false (失敗)
  */
    private boolean movement(String source, String destination, String filename) throws Exception {

        boolean ret = false;
        xcopy xc = new xcopy();

        String source_name      = source + File.separator + filename;
        String destination_name = destination + File.separator + filename;
        File source_file = new File(source_name);
        File destination_file = new File(destination_name);

        //存在確認
        ret = source_file.exists();
        if (ret) {

            // ディレクトリの場合
            if ( source_file.isDirectory() ) {
                // admin/team/publicディレクトリの場合
                if ( source_name.equalsIgnoreCase(pr_adminDir) ) {
                    // Adminディレクトリの移動
                    ret = admin_directory(source_name, destination_name);
                } else if ( source_name.equalsIgnoreCase(pr_teamDir) || source_name.equalsIgnoreCase(pr_publicDir) ) {
                    // Portal____ディレクトリの移動
                    ret = portal_directory(source_name, destination_name);
                } else {
                    // それ以外の移動
                    ret = xc.directory(source_name, destination_name);
                }

            } else if ( source_file.isFile() ) {
                // ファイルの移動
                ret = xc.file(source_name, destination_name);
            }

        }
        return ret;
    }


/**
  * Adminディレクトリのコピー
  *
  * Admin直下のXXX_navi.htmlのみ、背景色を変更してコピーする
  *
  * @param  String      source          移動元ディレクトリ名
  * @param  String      destination     移動先ディレクトリ名
  *
  * @return boolean     true(成功) / false (失敗)
  */
    private boolean admin_directory(String source, String destination) throws Exception {

        boolean ret = false;
        xcopy xc = new xcopy();
        File source_file = new File(source);
        File destination_file = new File(destination);

        // ディレクトリの有無
        ret = source_file.exists();
        if (ret){

            //ディレクトリの生成／日付変更
            ret = xc.makeDir(destination);
            if (ret) destination_file.setLastModified(source_file.lastModified());

            // ファイルおよびディレクトリのリストを取得
            String[] source_lst =  source_file.list();

            //ファイルまたはサブディレクトリを削除
            for (int n = 0; n < source_lst.length; n++) {
                String lowerFile = source_lst[n].toLowerCase();

                if ( (lowerFile.lastIndexOf(pr_naviHtml) != -1) || 
                     (lowerFile.lastIndexOf(pr_naviHtm)  != -1) ) {
                    // _navi.htmlの場合
                    ret = navi_move(source + File.separator + source_lst[n], destination + File.separator + source_lst[n]); 
                } else {
                    // _navi.htmlでない場合
                    ret = movement(source,  destination, source_lst[n]);
                }
            }
        }
        return ret;
    }




/**
  * portalディレクトリのコピー
  *
  * portalのXXX_navi.htmlのみ、背景色を変更してコピーする
  * （サブディレクトリも含む）
  *
  *
  * @param  String      source          移動元ディレクトリ名
  * @param  String      destination     移動先ディレクトリ名
  *
  * @return boolean     true(成功) / false (失敗)
  */
    private boolean portal_directory(String source, String destination) throws Exception {

        boolean ret = false;
        xcopy xc = new xcopy();
        File source_file = new File(source);
        File destination_file = new File(destination);

        // ディレクトリの有無
        ret = source_file.exists();
        if (ret){

            //ディレクトリの生成／日付変更
            ret = xc.makeDir(destination);
            if (ret) destination_file.setLastModified(source_file.lastModified());

            // ファイルおよびディレクトリのリストを取得
            String[] source_lst =  source_file.list();

            //ファイルまたはサブディレクトリを削除
            for (int n = 0; n < source_lst.length; n++) {
                ret = portal_movement(source, destination, source_lst[n]);
            }
        }
        return ret;
    }



/**
  * portalディレクトリの分岐
  *
  * @param  String      source          移動元ディレクトリ名
  * @param  String      destination     移動先ディレクトリ名
  * @param  String      filename        ファイル名
  *
  * @return boolean     true(成功) / false (失敗)
  */
    private boolean portal_movement(String source, String destination, String filename) throws Exception {

        boolean ret = false;
        xcopy xc = new xcopy();
        String source_name      = source + File.separator + filename;
        String destination_name = destination + File.separator + filename;
        File source_file = new File(source_name);
        File destination_file = new File(destination_name);

        //存在確認
        ret = source_file.exists();
        if (ret) {
            if (source_file.isDirectory()) {
                //ディレクトリの場合
                ret = portal_directory(source_name, destination_name);
            } else if (source_file.isFile() ) {
                //ファイルの場合
                String lowerFile = source_name.toLowerCase();
                if ( (lowerFile.lastIndexOf(pr_naviHtml) != -1) || 
                     (lowerFile.lastIndexOf(pr_naviHtm)  != -1) ) {
                    // _navi.html / _navi.htm の場合
                    ret = navi_move(source_name, destination_name); 
                } else {
                    // ファイルの移動
                    ret = xc.file(source_name, destination_name);
                }
            }
        }
        return ret;
    }


/**
  * ナビバーのＨＴＭＬファイルを移動
  *
  * @param  String      source          移動元ディレクトリ名
  * @param  String      destination     移動先ディレクトリ名
  *
  * @return boolean     true(成功) / false (失敗)
  */
    private boolean navi_move(String source, String destination) throws Exception {
        
        if (pr_bgColor == "") pr_bgColor = pr_gray;
        HtmlMapper mapper = new HtmlMapper();
        mapper.replaceHtmlTagAttribute(source, destination, "body", "bgcolor", pr_bgColor);

        //日付の変更
        File source_move = new File(source);
        File destination_move = new File(destination);
        destination_move.setLastModified(source_move.lastModified());

        return true;
    }


/**
  * 現在の時刻を文字列で取得する(yyyyMdd_HHmmssSSS)
  *
  * @return String  (yyyyMdd_HHmmssSSS)
  */
    public String time_stamp() {

        String timestamp;
        Date date = new Date();
        DateFormat df = new SimpleDateFormat("yyyyMMdd_HHmmssSSS");
        timestamp = df.format(date);
        return timestamp;
    }

}
