/*
 * FileOperation03ListTest class.
 *
 * Copyright (C) 2007 SATOH Takayuki All Rights Reserved.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */
package ts.util.file;

import ts.tester.function.*;
import ts.tester.function.print.*;
import java.io.*;
import java.util.*;

/**
 * {@link ts.util.file.FileOperation03List FileOperation03List}クラスの機能試験クラス。
 *
 * @author  佐藤隆之.
 * @version $Revision: 1.1.1.1 $, $Date: 2010-10-16 00:03:46 $
 */
public class FileOperation03ListTest extends FunctionTester
{
  public static void main(String[] args)
  {
    try {
      run(FileOperation03ListTest.class, (args.length == 0) ? null : args[0]);
    }
    catch (Exception e) {
      e.printStackTrace();
    }
  }

  final File WORKDIR = new File("test/data/ts/util/file/FileOperation");
  File[] DIRS = new File[6];
  File[] FILES = new File[10];

  protected void preInvocation(String method)
  {
    WORKDIR.mkdirs();
    DIRS[0] = new File(WORKDIR, "DIRS0");
    DIRS[1] = new File(DIRS[0], "DIRS1");
    DIRS[2] = new File(DIRS[0], "DIRS2");
    DIRS[3] = new File(DIRS[1], "DIRS3");
    DIRS[4] = new File(DIRS[2], "DIRS4");
    DIRS[5] = new File(DIRS[2], "DIRS5");
    FILES[0] = new File(DIRS[0], "FILES0");
    FILES[1] = new File(DIRS[1], "FILES1");
    FILES[2] = new File(DIRS[2], "FILES2");
    FILES[3] = new File(DIRS[3], "FILES3");
    FILES[4] = new File(DIRS[4], "FILES4");
    FILES[5] = new File(DIRS[0], "FILES5");
    FILES[6] = new File(DIRS[1], "FILES6");
    FILES[7] = new File(DIRS[2], "FILES7");
    FILES[8] = new File(DIRS[3], "FILES8");
    FILES[9] = new File(DIRS[4], "FILES9");
    try {
      for (File d : DIRS) d.mkdirs();
      for (File f : FILES) f.createNewFile();
    } catch (Exception e) {}

    /*
       DIRS[0]
        +- DIRS[1]
          +- DIRS[3]
            +- FILES[3]
            +- FILES[8]
          +- FILES[1]
          +- FILES[6]
        +- DIRS[2]
          +- DIRS[4]
            +- FILES[4]
            +- FILES[9]
          +- DIRS[5]
          +- FILES[2]
          +- FILES[7]
        +- FILES[0]
        +- FILES[5]
    */
  }

  protected void postInvocation(String method)
  {
    try {
      FileOperation.deleteRecursive(WORKDIR);
    } catch (Exception e) {}
  }

  /* -- test case -- */

  public void list()
  {
    MSG("指定したディレクトリ直下のファイルの一覧の取得。");
    
    try {
      List<File> lst = FileOperation.list(DIRS[2]);
      EQUAL(lst.size(), 4);
      int i = 0;
      EQUAL(lst.get(i++), DIRS[4]);
      EQUAL(lst.get(i++), DIRS[5]);
      EQUAL(lst.get(i++), FILES[2]);
      EQUAL(lst.get(i++), FILES[7]);
    } catch (Exception e) {
      NG(e);
    }
  }

  public void list_01()
  {
    MSG("引数がヌルの場合。");

    try {
      FileOperation.list(null);
      NG();
    } catch (AssertionError e) {
      OK(e);
    } catch (Exception e) {
      NG(e);
    }
  }

  public void list_02()
  {
    MSG("引数が空のディレクトリの場合。");

    try {
      List<File> lst = FileOperation.list(DIRS[5]);
      EQUAL(lst.size(), 0);
    } catch (Exception e) {
      NG(e);
    }
  }

  public void list_03()
  {
    MSG("引数が空でないディレクトリの場合。");

    try {
      List<File> lst = FileOperation.list(DIRS[3]);
      EQUAL(lst.size(), 2);
      EQUAL(lst.get(0), FILES[3]);
      EQUAL(lst.get(1), FILES[8]);
    } catch (Exception e) {
      NG(e);
    }
  }

  public void list_04()
  {
    MSG("引数が通常のファイルの場合。");

    try {
      List<File> lst = FileOperation.list(FILES[1]);
      EQUAL(lst.size(), 1);
      EQUAL(lst.get(0), FILES[1]);
    } catch (Exception e) {
      NG(e);
    }
  }

  public void list_05()
  {
    MSG("存在しないディレクトリ／ファイルの場合。");

    try {
      List<File> lst = FileOperation.list(new File(WORKDIR, "abc"));
      NG();
    } catch (FileNotFoundException e) {
      OK(e);
    } catch (Exception e) {
      NG(e);
    }
  }

  public void list_06()
  {
    MSG("ファイルが共有ロック中の場合。");

    try {
      FileOperationTest.lockFile("shared", FILES[3]);
      Thread.sleep(1000);
    } catch (Exception e) {
      NG(e);
    }

    try {
      List<File> lst = FileOperation.list(FILES[3]);
      EQUAL(lst.size(), 1);
      EQUAL(lst.get(0), FILES[3]);

      lst = FileOperation.list(DIRS[3]);
      EQUAL(lst.size(), 2);
      EQUAL(lst.get(0), FILES[3]);
      EQUAL(lst.get(1), FILES[8]);

      Thread.sleep(1000);
    } catch (Exception e) {
      NG(e);
    } finally {
      FileOperationTest.releaseLock();
    }
  }

  public void list_07()
  {
    MSG("ファイルが排他ロック中の場合。");

    try {
      FileOperationTest.lockFile("exclusive", FILES[4]);
      Thread.sleep(1000);
    } catch (Exception e) {
      NG(e);
    }

    try {
      List<File> lst = FileOperation.list(FILES[4]);
      EQUAL(lst.size(), 1);
      EQUAL(lst.get(0), FILES[4]);

      lst = FileOperation.list(DIRS[4]);
      EQUAL(lst.size(), 2);
      EQUAL(lst.get(0), FILES[4]);
      EQUAL(lst.get(1), FILES[9]);

      Thread.sleep(1000);
    } catch (Exception e) {
      NG(e);
    } finally {
      FileOperationTest.releaseLock();
    }
  }

  public void list_08()
  {
    MSG("下位のファイル一覧を取得できなかった場合。");

    File f0 = new File(WORKDIR, "aaa") {
      static final long serialVersionUID = 1L;
      public File[] listFiles() { return null; }
    };
    f0.mkdirs();

    try {
      FileOperation.list(f0);
      NG();
    } catch (IOException e) {  
      OK(e);
    } catch (Exception e) {
      NG(e);
    }
  }

  public void list_filter()
  {
    MSG("フィルタを使ったファイルの一覧。");
    
    try {
      List<File> fL;
      fL = FileOperation.list(FILES[1], new FileNameRegexFilter(".*1"));
      EQUAL(fL.size(), 1);
      EQUAL(fL.get(0), FILES[1]);

      fL = FileOperation.list(FILES[6], new FileNameRegexFilter(".*1"));
      EQUAL(fL.size(), 0);

      fL = FileOperation.list(DIRS[1], new FileNameRegexFilter(".*1"));
      EQUAL(fL.size(), 1);
      EQUAL(fL.get(0), FILES[1]);

    } catch (Exception e) {
      NG(e);
    }
  }

  public void list_filter_0()
  {
    MSG("引数がヌルの場合。");

    try {
      FileOperation.list((File) null, new FileTypeFilter(FileType.File));
      NG();
    } catch (AssertionError e) {
      OK(e);
    } catch (Exception e) {
      NG(e);
    }

    try {
      FileOperation.list(FILES[1], (FileFilter) null);
      NG();
    } catch (AssertionError e) {
      OK(e);
    } catch (Exception e) {
      NG(e);
    }
  }

  public void listRecursive()
  {
    MSG("ディレクトリ内のファイルを再帰的にリスト・アップ。");
    
    try {
      List<File> lst = FileOperation.listRecursive(DIRS[2]);
      EQUAL(lst.size(), 6);
      int i = 0;
      EQUAL(lst.get(i++), DIRS[4]);
      EQUAL(lst.get(i++), FILES[4]);
      EQUAL(lst.get(i++), FILES[9]);
      EQUAL(lst.get(i++), DIRS[5]);
      EQUAL(lst.get(i++), FILES[2]);
      EQUAL(lst.get(i++), FILES[7]);
    } catch (Exception e) {
      NG(e);
    }
  }

  public void listRecursive_1()
  {
    MSG("引数がヌルの場合。");

    try {
      FileOperation.listRecursive(null);
      NG();
    } catch (AssertionError e) {
      OK(e);
    } catch (Exception e) {
      NG(e);
    }
  }

  public void listRecursive_2()
  {
    MSG("引数がディレクトリでない場合。");

    try {
      List<File> lst = FileOperation.listRecursive(FILES[1]);
      EQUAL(lst.size(), 1);
      EQUAL(lst.get(0), FILES[1]);
    } catch (Exception e) {
      NG(e);
    }
  }

  public void listRecursive_3()
  {
    MSG("存在しないファイルを指定した場合。");

    File dir = new File(WORKDIR, "llll");

    try {
      FileOperation.listRecursive(dir);
      NG();
    } catch (FileNotFoundException e) {
      OK(e);
    } catch (Exception e) {
      NG(e);
    }
  }

  public void listRecursive_4()
  {
    MSG("ファイルが共有ロック中の場合。");

    try {
      FileOperationTest.lockFile("shared", FILES[3]);
      Thread.sleep(1000);
    } catch (Exception e) {
      NG(e);
    }

    try {
      List<File> lst = FileOperation.listRecursive(FILES[3]);
      EQUAL(lst.size(), 1);
      EQUAL(lst.get(0), FILES[3]);

      lst = FileOperation.listRecursive(DIRS[3]);
      EQUAL(lst.size(), 2);
      EQUAL(lst.get(0), FILES[3]);
      EQUAL(lst.get(1), FILES[8]);

      Thread.sleep(1000);
    } catch (Exception e) {
      NG(e);
    } finally {
      FileOperationTest.releaseLock();
    }
  }

  public void listRecursive_5()
  {
    MSG("ファイルが排他ロック中の場合。");

    try {
      FileOperationTest.lockFile("exclusive", FILES[4]);
      Thread.sleep(1000);
    } catch (Exception e) {
      NG(e);
    }

    try {
      List<File> lst = FileOperation.listRecursive(FILES[4]);
      EQUAL(lst.size(), 1);
      EQUAL(lst.get(0), FILES[4]);

      lst = FileOperation.listRecursive(DIRS[4]);
      EQUAL(lst.size(), 2);
      EQUAL(lst.get(0), FILES[4]);
      EQUAL(lst.get(1), FILES[9]);

      Thread.sleep(1000);
    } catch (Exception e) {
      NG(e);
    } finally {
      FileOperationTest.releaseLock();
    }
  }

  public void listRecursive_file_filter()
  {
    MSG("フィルタを使ったファイルの一覧。");

    try {
      List<File> fL;
      fL=FileOperation.listRecursive(FILES[3],new FileNameRegexFilter(".*3"));
      EQUAL(fL.size(), 1);
      EQUAL(fL.get(0), FILES[3]);

      fL=FileOperation.listRecursive(FILES[8],new FileNameRegexFilter(".*3"));
      EQUAL(fL.size(), 0);

      fL=FileOperation.listRecursive(DIRS[1],new FileNameRegexFilter(".*[36]"));
      EQUAL(fL.size(), 3);
      int i=0;
      EQUAL(fL.get(i++), DIRS[3]); 
      EQUAL(fL.get(i++), FILES[3]);
      EQUAL(fL.get(i++), FILES[6]);
    } catch (Exception e) {
      NG(e);
    }
  }

  public void listRecursive_file_filter_1()
  {
    MSG("引数がヌルの場合。");

    try {
      FileOperation.listRecursive((File) null, new FileNameRegexFilter(".*1"));
      NG();
    } catch (AssertionError e) {
      OK(e);
    } catch (Exception e) {
      NG(e);
    }

    try {
      FileOperation.listRecursive(DIRS[3], null);
      NG();
    } catch (AssertionError e) {
      OK(e);
    } catch (Exception e) {
      NG(e);
    }
  }
}

