/*
 * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
 * or more contributor license agreements. Licensed under the Elastic License;
 * you may not use this file except in compliance with the Elastic License.
 */
package org.elasticsearch.shield.crypto.tool;

import com.google.common.jimfs.Configuration;
import com.google.common.jimfs.Jimfs;
import org.elasticsearch.cli.Command;
import org.elasticsearch.cli.CommandTestCase;
import org.elasticsearch.common.io.PathUtilsForTesting;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.env.Environment;
import org.elasticsearch.shield.crypto.InternalCryptoService;
import org.junit.Before;

import java.nio.file.FileSystem;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.attribute.PosixFileAttributeView;
import java.nio.file.attribute.PosixFilePermission;
import java.util.Set;

public class SystemKeyToolTests extends CommandTestCase {

    private FileSystem jimfs;
    private Settings.Builder settingsBuilder;
    private Path homeDir;

    @Before
    public void init() throws Exception {
        String view = randomFrom("basic", "posix");
        Configuration conf = Configuration.unix().toBuilder().setAttributeViews(view).build();
        jimfs = Jimfs.newFileSystem(conf);
        PathUtilsForTesting.installMock(jimfs);
        homeDir = jimfs.getPath("eshome");

        settingsBuilder = Settings.builder()
            .put(Environment.PATH_HOME_SETTING.getKey(), homeDir);
    }

    @Override
    protected Command newCommand() {
        return new SystemKeyTool(new Environment(settingsBuilder.build()));
    }

    public void testGenerate() throws Exception {
        Path path = jimfs.getPath(randomAsciiOfLength(10)).resolve("key");
        Files.createDirectory(path.getParent());
        execute(path.toString());
        byte[] bytes = Files.readAllBytes(path);
        // TODO: maybe we should actually check the key is...i dunno...valid?
        assertEquals(InternalCryptoService.KEY_SIZE / 8, bytes.length);

        Set<PosixFilePermission> perms = Files.getPosixFilePermissions(path);
        assertTrue(perms.toString(), perms.contains(PosixFilePermission.OWNER_READ));
        assertTrue(perms.toString(), perms.contains(PosixFilePermission.OWNER_WRITE));
        assertEquals(perms.toString(), 2, perms.size());
    }

    public void testGeneratePathInSettings() throws Exception {
        Path path = jimfs.getPath(randomAsciiOfLength(10)).resolve("key");
        Files.createDirectories(path.getParent());
        settingsBuilder.put("shield.system_key.file", path.toAbsolutePath().toString());
        execute();
        byte[] bytes = Files.readAllBytes(path);
        assertEquals(InternalCryptoService.KEY_SIZE / 8, bytes.length);
    }

    public void testGenerateDefaultPath() throws Exception {
        Path keyPath = homeDir.resolve("config/x-pack/system_key");
        Files.createDirectories(keyPath.getParent());
        execute();
        byte[] bytes = Files.readAllBytes(keyPath);
        assertEquals(InternalCryptoService.KEY_SIZE / 8, bytes.length);
    }

    public void testThatSystemKeyMayOnlyBeReadByOwner() throws Exception {
        Path path = jimfs.getPath(randomAsciiOfLength(10)).resolve("key");
        Files.createDirectories(path.getParent());
        boolean isPosix = Files.getFileAttributeView(path.getParent(), PosixFileAttributeView.class) != null;
        assumeTrue("posix filesystem", isPosix);

        execute(path.toString());
        Set<PosixFilePermission> perms = Files.getPosixFilePermissions(path);
        assertTrue(perms.toString(), perms.contains(PosixFilePermission.OWNER_READ));
        assertTrue(perms.toString(), perms.contains(PosixFilePermission.OWNER_WRITE));
        assertEquals(perms.toString(), 2, perms.size());
    }
}

@@ -664,33 +664,8 @@
 ice;
-%0Aimport org.junit.Before;
 %0A%0Aim
@@ -754,63 +754,8 @@
 th;%0A
-import java.nio.file.attribute.PosixFileAttributeView;%0A
 impo
@@ -995,37 +995,54 @@
     
-@Before%0A    public void init(
+private void initFileSystem(boolean needsPosix
 ) th
@@ -1079,16 +1079,39 @@
 g view =
+ needsPosix ? %22posix%22 :
  randomF
@@ -1658,32 +1658,63 @@
 ows Exception %7B%0A
+        initFileSystem(true);%0A%0A
         Path pat
@@ -1813,32 +1813,33 @@
 h.getParent());%0A
+%0A
         execute(
@@ -2427,32 +2427,64 @@
 ows Exception %7B%0A
+        initFileSystem(false);%0A%0A
         Path pat
@@ -2882,32 +2882,63 @@
 ows Exception %7B%0A
+        initFileSystem(false);%0A
         Path key
@@ -3260,32 +3260,63 @@
 ows Exception %7B%0A
+        initFileSystem(true);%0A%0A
         Path pat
@@ -3366,32 +3366,32 @@
 resolve(%22key%22);%0A
+
         Files.cr
@@ -3428,167 +3428,8 @@
 ());
-%0A        boolean isPosix = Files.getFileAttributeView(path.getParent(), PosixFileAttributeView.class) != null;%0A        assumeTrue(%22posix filesystem%22, isPosix);
 %0A%0A  

Fix systemkeytool tests