/**
 * Configurate
 * Copyright (C) zml and Configurate contributors
 *
 * 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 ninja.leaping.configurate.loader;

import com.google.common.base.Preconditions;

import java.io.BufferedWriter;
import java.io.FilterWriter;
import java.io.IOException;
import java.io.Writer;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardCopyOption;
import java.util.concurrent.Callable;

public class AtomicFiles {
    private AtomicFiles() {}

    public static Callable<BufferedWriter> createAtomicWriterFactory(Path path, Charset charset) {
        Preconditions.checkNotNull(path, "path");
        return () -> createAtomicBufferedWriter(path, charset);
    }

    public static BufferedWriter createAtomicBufferedWriter(Path path, Charset charset) throws IOException {
        path = path.toAbsolutePath();
        Path writePath = Files.createTempFile(path.getParent(), path.getFileName().toString().replaceAll("\\\\|/|:", "-"), null);
        BufferedWriter output = Files.newBufferedWriter(writePath, charset);
        return new BufferedWriter(new AtomicFileWriter(writePath, path, output));
    }

    private static class AtomicFileWriter extends FilterWriter {
        private final Path targetPath, writePath;

        protected AtomicFileWriter(Path writePath, Path targetPath, Writer wrapping) throws IOException {
            super(wrapping);
            this.writePath = writePath;
            this.targetPath = targetPath;
        }

        @Override
        public void close() throws IOException {
            super.close();
            Files.move(writePath, targetPath, StandardCopyOption.ATOMIC_MOVE, StandardCopyOption.REPLACE_EXISTING);
        }
    }
}

@@ -948,24 +948,70 @@
 CopyOption;%0A
+import java.nio.file.attribute.FileAttribute;%0A
 import java.
@@ -1064,16 +1064,104 @@
 Files %7B%0A
+    private static final FileAttribute%3C?%3E%5B%5D EMPTY_ATTRIBUTE_ARR = new FileAttribute%5B0%5D;%0A
     priv
@@ -1398,24 +1398,288 @@
 et);%0A    %7D%0A%0A
+    private static Path getTemporaryPath(Path parent, String key) %7B%0A        String fileName = System.currentTimeMillis() + Preconditions.checkNotNull(key, %22key%22).replaceAll(%22%5C%5C%5C%5C%7C/%7C:%22,%0A                %22-%22) + %22.tmp%22;%0A        return parent.resolve(fileName);%0A    %7D%0A%0A
     public s
@@ -1809,24 +1809,25 @@
 lutePath();%0A
+%0A
         Path
@@ -1843,28 +1843,24 @@
 h = 
-Files.createTempFile
+getTemporaryPath
 (pat
@@ -1907,44 +1907,132 @@
 ng()
-.replaceAll(%22%5C%5C%5C%5C%7C/%7C:%22, %22-%22), null);
+);%0A        if (Files.exists(path)) %7B%0A            Files.copy(path, writePath, StandardCopyOption.COPY_ATTRIBUTES);%0A        %7D%0A
 %0A   

Fix permissions on files written by configurate