/*
 * Copyright 2018 Scytl Secure Electronic Voting SA
 *
 * All rights reserved
 *
 * See our extended copyright notice in *file 'Copyright.txt'
 * which is part of this source code package
 */

package com.scytl.slogger.policy;

import com.scytl.slogger.CleanDirProvider;

import java.io.File;
import java.util.Iterator;

import junit.framework.TestCase;

public class SequentialDateFileNamePolicyTest extends TestCase {

  private static final int LOG_FILES = 100;

  private static final String LOG_FILE = "sequential-date-test.log";

  private static final String INDEX = "INDEX";

  private static final String DATE = "DATE";

  private static final String LOG_FILE_X = "sequential-date-test-" + DATE + "-" + INDEX + ".log";

  private File baseLogFile;

  private SequentialDateFileNamePolicy policy;

  public void testDeletedLogFile() throws Exception {
    // Manipulated files
    File file1 = new File(CleanDirProvider.getCleanedTmpDir().getAbsolutePath(),
        LOG_FILE_X.replace(INDEX, "0").replace(DATE, "19800101-000000"));
    file1.createNewFile();

    File file2 = new File(CleanDirProvider.getTmpDir().getAbsolutePath(),
        LOG_FILE_X.replace(INDEX, "1").replace(DATE, "19800102-000000"));
    file2.createNewFile();

    File file3 = new File(CleanDirProvider.getTmpDir().getAbsolutePath(),
        LOG_FILE_X.replace(INDEX, "2").replace(DATE, "19800103-000000"));
    file3.createNewFile();

    policy.logFiles();
    assertEquals(file3, policy.lastLogFile());

    file2.delete();
    try {
      policy.nextLogFile();
      expectedFail();
    } catch (LogFileNamePolicyException e) {
      // expected exception
    }

    try {
      policy.lastLogFile();
      expectedFail();
    } catch (LogFileNamePolicyException e) {
      // expected exception
    }

    try {
      policy.logFiles();
      expectedFail();
    } catch (LogFileNamePolicyException e) {
      // expected exception
    }
  }

  public void testFailFilePolicy() throws Exception {
    // Future file (date)
    File futureFile = new File(CleanDirProvider.getCleanedTmpDir().getAbsolutePath(),
        LOG_FILE_X.replace(INDEX, "0").replace(DATE, "21000101-000000"));
    futureFile.createNewFile();

    try {
      policy.nextLogFile();
      expectedFail();
    } catch (LogFileNamePolicyException e) {
      // expected exception
    }

    // Future file (index)
    futureFile = new File(CleanDirProvider.getCleanedTmpDir().getAbsolutePath(),
        LOG_FILE_X.replace(INDEX, "1").replace(DATE, "19700101-000000"));
    futureFile.createNewFile();

    try {
      policy.nextLogFile();
      expectedFail();
    } catch (LogFileNamePolicyException e) {
      // expected exception
    }

  }

  public void testFilePolicy() throws Exception {
    // No log files
    assertFalse(policy.logFiles().hasNext());
    assertNull(policy.lastLogFile());

    // Multiple files created
    File[] expectedFiles = new File[LOG_FILES];
    for (int index = 0; index < LOG_FILES; index++) {
      File nextLogFile = policy.nextLogFile();
      nextLogFile.createNewFile();
      File lastLogFile = policy.lastLogFile();
      assertEquals(nextLogFile, lastLogFile);
      expectedFiles[index] = nextLogFile;
    }

    int logFilesIndex = 0;
    for (Iterator<File> it = policy.logFiles(); it.hasNext();) {
      assertEquals(it.next(), expectedFiles[logFilesIndex]);
      logFilesIndex++;
    }

    assertEquals(logFilesIndex, LOG_FILES);
  }

  @Override
  protected void setUp() throws Exception {
    baseLogFile = new File(CleanDirProvider.getCleanedTmpDir().getAbsolutePath(), LOG_FILE);
    policy = new SequentialDateFileNamePolicy(baseLogFile);
  }

  @Override
  protected void tearDown() throws Exception {
    CleanDirProvider.deleteTmpDir();
  }

  private void expectedFail() {
    fail("Exception expected");
  }

}
