/*
 * 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 static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;

import com.scytl.slogger.CleanDirProvider;

import org.junit.Before;
import org.junit.Test;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.util.Iterator;
import java.util.Scanner;

public class RollingSequentialFileNamePolicyTest {

  private static final int LOG_FILES = 100;

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

  private static final String INDEX = "INDEX";

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

  private File _baseLogFile;

  @Before
  public void setUp() throws Exception {
    _baseLogFile = new File(CleanDirProvider.getCleanedTmpDir().getAbsolutePath(), LOG_FILE);
  }

  @Test
  public void testFilePolicy() throws Exception {
    RollingSequentialFileNamePolicy policy = new RollingSequentialFileNamePolicy(_baseLogFile);

    // No log files
    assertFalse(policy.logFiles().hasNext());
    File logFile = policy.nextLogFile();
    writeLine(logFile, "Aguante Boca Juniors");
    assertEquals(logFile, new File(_baseLogFile.getAbsolutePath()));
    assertNull(policy.lastLogFile());

    // Multiple log files
    for (int i = 0; i < LOG_FILES; i++) {
      policy.closeCurrentFile();
      File nextLogFile = policy.nextLogFile();
      String line = "Time:" + System.currentTimeMillis();
      writeLine(nextLogFile, line);
      File expectedLoggedFile = new File(CleanDirProvider.getTmpDir().getAbsolutePath(), LOG_FILE);
      assertTrue("missing file", expectedLoggedFile.exists());
      Scanner scanner = new Scanner(expectedLoggedFile);
      assertEquals("wrong content", line, scanner.nextLine());
      scanner.close();

      int index = 0;
      for (Iterator<File> logFiles = policy.logFiles(); logFiles.hasNext();) {

        File nextFile = logFiles.next();
        // check for base log file name reached
        if (logFiles.hasNext()) {
          break;
        }
        expectedLoggedFile = new File(CleanDirProvider.getTmpDir().getAbsolutePath(),
            LOG_FILE_X.replace(INDEX, "" + index));
        assertEquals(expectedLoggedFile, nextFile);
        index++;
      }
      assertEquals(nextLogFile, new File(CleanDirProvider.getTmpDir().getAbsolutePath(), LOG_FILE));
    }
  }

  /**
   * @param logFile
   * @throws FileNotFoundException
   * @throws IOException
   */
  private void writeLine(final File logFile, final String line)
      throws FileNotFoundException, IOException {
    OutputStreamWriter out = new OutputStreamWriter(new FileOutputStream(logFile));
    out.write(line);
    out.close();
  }
}
