/*
 * Copyright 2021 ThoughtWorks, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.thoughtworks.go.util;

import java.io.File;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.List;

import com.thoughtworks.go.domain.DirectoryEntry;
import com.thoughtworks.go.domain.FolderDirectoryEntry;
import com.thoughtworks.go.domain.JobIdentifier;
import static org.hamcrest.Matchers.is;

import static org.hamcrest.MatcherAssert.assertThat;

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;


public class DirectoryReaderTest {
    @TempDir
    File testFolder;
    private JobIdentifier jobIdentifier;
    private String folderRoot;

    @BeforeEach
    public void setUp() throws IOException {
        jobIdentifier = new JobIdentifier("pipelineName", -1, "LATEST", "stageName", "LATEST", "buildName", 123L);
        folderRoot = "/" + testFolder.getName();
    }

    @Test
    public void shouldNotDieIfGivenBogusPath() throws Exception {
        DirectoryReader reader = new DirectoryReader(jobIdentifier);
        List<DirectoryEntry> entries = reader.listEntries(new File("totally bogus path!!!"), "");
        assertThat(entries.size(), is(0));
    }

    @Test
    public void shouldNotDieIfGivenBogusFile() {
        DirectoryReader reader = new DirectoryReader(jobIdentifier);
        List<DirectoryEntry> entries = reader.listEntries(null, "");
        assertThat(entries.size(), is(0));
    }

    @Test
    public void shouldGetFileList() throws Exception {
        String filename = "text.html$%";
        TestFileUtil.createTestFile(testFolder, filename);
        DirectoryReader reader = new DirectoryReader(jobIdentifier);
        List<DirectoryEntry> entries = reader.listEntries(testFolder, folderRoot);
        assertThat(entries.size(), is(1));
        assertThat(entries.get(0).getFileName(), is(filename));
        assertThat(entries.get(0).getUrl(),
                is("/files/pipelineName/LATEST/stageName/LATEST/buildName" + folderRoot + "/"
                        + URLEncoder.encode(filename)));
    }

    @Test
    public void shouldGetSubSubFolder() throws Exception {
        TestFileUtil.createTestFile(TestFileUtil.createTestFolder(TestFileUtil.createTestFolder(testFolder, "primate"), "monkey"), "baboon.html");
        DirectoryReader reader = new DirectoryReader(jobIdentifier);
        List<DirectoryEntry> entries = reader.listEntries(testFolder, folderRoot);
        FolderDirectoryEntry folder = (FolderDirectoryEntry) entries.get(0);
        assertThat(folder.getFileName(), is("primate"));
        FolderDirectoryEntry subFolder = (FolderDirectoryEntry) folder.getSubDirectory().get(0);
        assertThat(subFolder.getFileName(), is("monkey"));
        assertThat(subFolder.getSubDirectory().get(0).getFileName(), is("baboon.html"));
        assertThat(subFolder.getSubDirectory().get(0).getUrl(),
                is("/files/pipelineName/LATEST/stageName/LATEST/buildName"
                        + folderRoot + "/primate/monkey/baboon.html"));
    }

    @Test
    public void shouldGetListOfFilesAndFolders() throws Exception {
        TestFileUtil.createTestFile(testFolder, "text.html");
        File subFolder = TestFileUtil.createTestFolder(testFolder, "primate");
        TestFileUtil.createTestFile(subFolder, "baboon.html");
        DirectoryReader reader = new DirectoryReader(jobIdentifier);
        List<DirectoryEntry> entries = reader.listEntries(testFolder, folderRoot);
        assertThat(entries.size(), is(2));
        FolderDirectoryEntry folder = (FolderDirectoryEntry) entries.get(0);
        assertThat(folder.getFileName(), is("primate"));
        assertThat(folder.getUrl(), is("/files/pipelineName/LATEST/stageName/LATEST/buildName"
                + folderRoot + "/primate"));
        assertThat(entries.get(1).getFileName(), is("text.html"));
        assertThat(folder.getSubDirectory().get(0).getFileName(), is("baboon.html"));
        assertThat(folder.getSubDirectory().get(0).getUrl(),
                is("/files/pipelineName/LATEST/stageName/LATEST/buildName" + folderRoot + "/primate/baboon.html"));
    }

    @Test
    public void shouldGetListOfFilesWithDirectoriesFirstAndFilesInAlphabeticOrder() throws Exception {
        TestFileUtil.createTestFile(testFolder, "build.html");
        File subFolder = TestFileUtil.createTestFolder(testFolder, "testoutput");
        TestFileUtil.createTestFile(subFolder, "baboon.html");
        TestFileUtil.createTestFile(subFolder, "apple.html");
        TestFileUtil.createTestFile(subFolder, "pear.html");
        DirectoryReader reader = new DirectoryReader(jobIdentifier);
        List<DirectoryEntry> entries = reader.listEntries(testFolder, folderRoot);
        assertThat(entries.size(), is(2));
        FolderDirectoryEntry folder = (FolderDirectoryEntry) entries.get(0);
        assertThat(folder.getFileName(), is("testoutput"));
        assertThat(entries.get(1).getFileName(), is("build.html"));
        assertThat(folder.getSubDirectory().get(0).getFileName(), is("apple.html"));
        assertThat(folder.getSubDirectory().get(1).getFileName(), is("baboon.html"));
        assertThat(folder.getSubDirectory().get(2).getFileName(), is("pear.html"));
    }

    @Test
    public void shouldNotContainSerializedObjectFile() throws Exception {
        String filename = ".log200806041535.xml.ser";
        TestFileUtil.createTestFile(testFolder, filename);
        DirectoryReader reader = new DirectoryReader(jobIdentifier);
        List<DirectoryEntry> entries = reader.listEntries(testFolder, folderRoot);
        assertThat(entries.size(), is(0));
    }

    @Test public void shouldKeepRootsInUrl() throws Exception {
        File b = TestFileUtil.createTestFolder(testFolder, "b");
        TestFileUtil.createTestFile(b, "c.xml");
        List<DirectoryEntry> entries = new DirectoryReader(jobIdentifier).listEntries(b, folderRoot + "/b");
        assertThat(entries.size(), is(1));
        String expectedUrl = "/files/pipelineName/LATEST/stageName/LATEST/buildName/"
                + testFolder.getName() + "/b/c.xml";
        assertThat(entries.get(0).getUrl(), is(expectedUrl));
    }

}

@@ -634,109 +634,8 @@
 l;%0A%0A
-import java.io.File;%0Aimport java.io.IOException;%0Aimport java.net.URLEncoder;%0Aimport java.util.List;%0A%0A
 impo
@@ -672,32 +672,32 @@
 DirectoryEntry;%0A
+
 import com.thoug
@@ -789,103 +789,8 @@
 er;%0A
-import static org.hamcrest.Matchers.is;%0A%0Aimport static org.hamcrest.MatcherAssert.assertThat;%0A%0A
 impo
@@ -903,16 +903,253 @@
 mpDir;%0A%0A
+import java.io.File;%0Aimport java.io.IOException;%0Aimport java.net.URLEncoder;%0Aimport java.nio.charset.StandardCharsets;%0Aimport java.util.List;%0A%0Aimport static org.hamcrest.MatcherAssert.assertThat;%0Aimport static org.hamcrest.Matchers.is;%0A%0A
 %0Apublic 
@@ -1517,32 +1517,32 @@
    %7D%0A%0A    @Test%0A
+
     public void 
@@ -1571,33 +1571,16 @@
 usPath()
- throws Exception
  %7B%0A     
@@ -2652,16 +2652,40 @@
 filename
+, StandardCharsets.UTF_8
 )));%0A   

FIx deprecated API usage