/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements. See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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 org.apache.logging.log4j.core.appender.rolling.action;

import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;

/**
 * File rename action.
 */
public class FileRenameAction extends AbstractAction {

    /**
     * Source.
     */
    private final File source;

    /**
     * Destination.
     */
    private final File destination;

    /**
     * If true, rename empty files, otherwise delete empty files.
     */
    private final boolean renameEmptyFiles;

    /**
     * Creates an FileRenameAction.
     *
     * @param src current file name.
     * @param dst new file name.
     * @param renameEmptyFiles if true, rename file even if empty, otherwise delete empty files.
     */
    public FileRenameAction(final File src, final File dst, final boolean renameEmptyFiles) {
        source = src;
        destination = dst;
        this.renameEmptyFiles = renameEmptyFiles;
    }

    /**
     * Rename file.
     *
     * @return true if successfully renamed.
     */
    @Override
    public boolean execute() {
        return execute(source, destination, renameEmptyFiles);
    }

    /**
     * Gets the destination.
     *
     * @return the destination.
     */
    public File getDestination() {
        return this.destination;
    }

    /**
     * Gets the source.
     *
     * @return the source.
     */
    public File getSource() {
        return this.source;
    }

    /**
     * Whether to rename empty files. If true, rename empty files, otherwise delete empty files.
     *
     * @return Whether to rename empty files.
     */
    public boolean isRenameEmptyFiles() {
        return renameEmptyFiles;
    }

    /**
     * Rename file.
     *
     * @param source current file name.
     * @param destination new file name.
     * @param renameEmptyFiles if true, rename file even if empty, otherwise delete empty files.
     * @return true if successfully renamed.
     */
    public static boolean execute(final File source, final File destination, final boolean renameEmptyFiles) {
        if (renameEmptyFiles || (source.length() > 0)) {
            final File parent = destination.getParentFile();
            if ((parent != null) && !parent.exists()) {
                // LOG4J2-679: ignore mkdirs() result: in multithreaded scenarios,
                // if one thread succeeds the other thread returns false
                // even though directories have been created. Check if dir exists instead.
                parent.mkdirs();
                if (!parent.exists()) {
                    LOGGER.error("Unable to create directory {}", parent.getAbsolutePath());
                    return false;
                }
            }
            try {
                try {
                    Files.move(Paths.get(source.getAbsolutePath()), Paths.get(destination.getAbsolutePath()),
                            StandardCopyOption.ATOMIC_MOVE, StandardCopyOption.REPLACE_EXISTING);
                    LOGGER.trace("Renamed file {} to {} with Files.move", source.getAbsolutePath(),
                            destination.getAbsolutePath());
                    return true;
                } catch (final IOException exMove) {
                    LOGGER.error("Unable to move file {} to {}: {} {}", source.getAbsolutePath(),
                            destination.getAbsolutePath(), exMove.getClass().getName(), exMove.getMessage());
                    boolean result = source.renameTo(destination);
                    if (!result) {
                        try {
                            Files.copy(Paths.get(source.getAbsolutePath()), Paths.get(destination.getAbsolutePath()),
                                    StandardCopyOption.REPLACE_EXISTING);
                            try {
                                Files.delete(Paths.get(source.getAbsolutePath()));
                                result = true;
                                LOGGER.trace("Renamed file {} to {} using copy and delete",
                                        source.getAbsolutePath(), destination.getAbsolutePath());
                            } catch (final IOException exDelete) {
                                LOGGER.error("Unable to delete file {}: {} {}", source.getAbsolutePath(),
                                        exDelete.getClass().getName(), exDelete.getMessage());
                                try {
                                    new PrintWriter(source.getAbsolutePath()).close();
                                    LOGGER.trace("Renamed file {} to {} with copy and truncation",
                                            source.getAbsolutePath(), destination.getAbsolutePath());
                                } catch (final IOException exOwerwrite) {
                                    LOGGER.error("Unable to overwrite file {}: {} {}",
                                            source.getAbsolutePath(), exOwerwrite.getClass().getName(),
                                            exOwerwrite.getMessage());
                                }
                            }
                        } catch (final IOException exCopy) {
                            LOGGER.error("Unable to copy file {} to {}: {} {}", source.getAbsolutePath(),
                                    destination.getAbsolutePath(), exCopy.getClass().getName(), exCopy.getMessage());
                        }
                    } else {
                        LOGGER.trace("Renamed file {} to {} with source.renameTo",
                                source.getAbsolutePath(), destination.getAbsolutePath());
                    }
                    return result;
                }
            } catch (final RuntimeException ex) {
                LOGGER.error("Unable to rename file {} to {}: {} {}", source.getAbsolutePath(),
                        destination.getAbsolutePath(), ex.getClass().getName(), ex.getMessage());
            }
        } else {
            try {
                source.delete();
            } catch (final Exception exDelete) {
                LOGGER.error("Unable to delete empty file {}: {} {}", source.getAbsolutePath(),
                        exDelete.getClass().getName(), exDelete.getMessage());
            }
        }

        return false;
    }

    @Override
    public String toString() {
        return FileRenameAction.class.getSimpleName() + '[' + source + " to " + destination
                + ", renameEmptyFiles=" + renameEmptyFiles + ']';
    }

}
