/*
 * Copyright 2017 Hewlett Packard Enterprise Development Company, L.P.
 * Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License.
 */

package com.hp.autonomy.frontend.find.idol.customization;

import com.hp.autonomy.frontend.find.core.test.AbstractFindIT;
import com.hp.autonomy.frontend.find.core.web.FindController;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.web.servlet.RequestBuilder;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.authentication;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.redirectedUrl;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

@DirtiesContext
public class CustomizationReloadControllerIT extends AbstractFindIT {
    private static final String UUID = "b1c71fad-a52d-47bf-a121-f71500bd7ddb";
    private static final String DASHBOARD_CONFIG = TEST_DIR + "/customization/dashboards.json";
    private static final String DASHBOARD_CONFIG_BACKUP = TEST_DIR + "/customization/dashboards.json.bak";
    private static final String REPLACEMENT_CONFIG = "target/test-classes/DashboardControllerIT-Config-1.json";

    @Override
    @Before
    public void setUp() {
        super.setUp();
        // Back up current config file

        try {
            for (int ii = 0; ii < 30 && !Files.exists(Paths.get(DASHBOARD_CONFIG)); ++ii) {
                Thread.sleep(1000);
            }
        }
        catch(InterruptedException e) {

        }

        copyFileReplaceExisting(DASHBOARD_CONFIG, DASHBOARD_CONFIG_BACKUP);
    }

    @After
    public void tearDown() {
        // Restore original config file, delete backup
        moveFileReplaceExisting(DASHBOARD_CONFIG_BACKUP, DASHBOARD_CONFIG);
    }

    @Test
    public void testReloadConfig() throws Exception {
        final String replacementConfigContents = new String(Files.readAllBytes(Paths.get(REPLACEMENT_CONFIG)), "UTF-8");
        assertTrue("Replacement config contains UUID", replacementConfigContents.contains(UUID));

        currentConfigContainsUUID(false);

        // Replace current config file
        copyFileReplaceExisting(REPLACEMENT_CONFIG, DASHBOARD_CONFIG);

        triggerConfigReload();

        currentConfigContainsUUID(true);
    }

    private void copyFileReplaceExisting(final String from, final String to) {
        final Path fromPath = Paths.get(from);
        final Path toPath = Paths.get(to);
        try {
            Files.copy(fromPath, toPath, StandardCopyOption.REPLACE_EXISTING);
        } catch(final IOException e) {
            throw new IllegalStateException("Could not replace current config file", e);
        }
    }

    private void moveFileReplaceExisting(final String from, final String to) {
        final Path fromPath = Paths.get(from);
        final Path toPath = Paths.get(to);
        try {
            Files.move(fromPath, toPath, StandardCopyOption.REPLACE_EXISTING);
        } catch(final IOException e) {
            throw new IllegalStateException("Could not replace current config file", e);
        }
    }

    private void currentConfigContainsUUID(final boolean expected) throws Exception {
        final RequestBuilder requestToAppPath = get(FindController.APP_PATH)
            .with(authentication(adminAuth()));

        mockMvc.perform(requestToAppPath)
            .andExpect(status().isOk())
            .andDo(mvcResult -> {
                final String response = mvcResult.getResponse().getContentAsString();
                assertEquals(expected, response.contains(UUID));
            });
    }

    private void triggerConfigReload() throws Exception {
        mockMvc.perform(
            get(CustomizationReloadController.ADMIN_CUSTOMIZATION_PATH +
                    CustomizationReloadController.CONFIG_RELOAD_PATH)
                .with(authentication(adminAuth())))
            .andExpect(status().isFound())
            .andExpect(redirectedUrl(FindController.APP_PATH));
    }
}

@@ -368,24 +368,58 @@
 Controller;%0A
+import lombok.extern.slf4j.Slf4j;%0A
 import org.j
@@ -426,24 +426,24 @@
 unit.After;%0A
-
 import org.j
@@ -1231,16 +1231,23 @@
 tatus;%0A%0A
+@Slf4j%0A
 @Dirties
@@ -1886,15 +1886,39 @@
 i %3C 
-30 && !
+60; ++ii) %7B%0A                if(
 File
@@ -1954,25 +1954,209 @@
 CONFIG))
-; ++ii) %7B
+) %7B%0A                    log.info(%22Dashboard file exists (%7B%7D)%22, ii);%0A                    break;%0A                %7D%0A                log.info(%22Dashboard file does not exist yet, waiting (%7B%7D)%22, ii);
 %0A       
@@ -2177,17 +2177,17 @@
 d.sleep(
-1
+2
 000);%0A  

Update test to increase startup delay and add logging; it's passing locally and on Travis, but fails on fenkins.