/*
 * 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.geode.internal.cache.backup;

import java.io.File;
import java.io.IOException;
import java.net.URISyntaxException;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.apache.commons.io.FileUtils;
import org.apache.logging.log4j.Logger;

import org.apache.geode.cache.DiskStore;
import org.apache.geode.distributed.DistributedSystem;
import org.apache.geode.internal.ClassPathLoader;
import org.apache.geode.internal.DeployedJar;
import org.apache.geode.internal.JarDeployer;
import org.apache.geode.internal.cache.DirectoryHolder;
import org.apache.geode.internal.cache.DiskStoreImpl;
import org.apache.geode.internal.cache.InternalCache;
import org.apache.geode.internal.cache.Oplog;
import org.apache.geode.internal.lang.SystemUtils;
import org.apache.geode.logging.internal.log4j.api.LogService;

class BackupFileCopier {
  private static final Logger logger = LogService.getLogger();

  private static final String CONFIG_DIRECTORY = "config";
  private static final String USER_FILES = "user";

  private final InternalCache cache;
  private final TemporaryBackupFiles temporaryFiles;
  private final BackupDefinition backupDefinition = new BackupDefinition();
  private final Path userDirectory;
  private final Path configDirectory;

  BackupFileCopier(InternalCache cache, TemporaryBackupFiles temporaryFiles) {
    this.cache = cache;
    this.temporaryFiles = temporaryFiles;
    userDirectory = temporaryFiles.getDirectory().resolve(USER_FILES);
    configDirectory = temporaryFiles.getDirectory().resolve(CONFIG_DIRECTORY);
  }

  BackupDefinition getBackupDefinition() {
    return backupDefinition;
  }

  void copyConfigFiles() throws IOException {
    ensureExistence(configDirectory);
    addConfigFileToBackup(cache.getCacheXmlURL());
    addConfigFileToBackup(DistributedSystem.getPropertiesFileURL());
    // TODO: should the gfsecurity.properties file be backed up?
  }

  private void ensureExistence(Path directory) throws IOException {
    if (!Files.exists(directory)) {
      Files.createDirectories(directory);
    }
  }

  private void addConfigFileToBackup(URL fileUrl) throws IOException {
    if (fileUrl == null) {
      return;
    }

    try {
      Path source = getSource(fileUrl);
      if (Files.notExists(source)) {
        return;
      }

      Path destination = configDirectory.resolve(source.getFileName());
      Files.copy(source, destination, StandardCopyOption.COPY_ATTRIBUTES);
      backupDefinition.addConfigFileToBackup(destination);
    } catch (URISyntaxException e) {
      throw new IOException(e);
    }
  }

  Set<File> copyUserFiles() throws IOException {
    ensureExistence(userDirectory);
    List<File> backupFiles = cache.getBackupFiles();
    Set<File> userFilesBackedUp = new HashSet<>();
    for (File original : backupFiles) {
      if (original.exists()) {
        original = original.getAbsoluteFile();
        Path destination = userDirectory.resolve(original.getName());
        if (original.isDirectory()) {
          FileUtils.copyDirectory(original, destination.toFile());
        } else {
          Files.copy(original.toPath(), destination, StandardCopyOption.COPY_ATTRIBUTES);
        }
        backupDefinition.addUserFilesToBackup(destination, original.toPath());
        userFilesBackedUp.add(original);
      }
    }
    return userFilesBackedUp;
  }

  Set<File> copyDeployedJars() throws IOException {
    ensureExistence(userDirectory);
    Set<File> userJars = new HashSet<>();
    JarDeployer deployer = null;
    try {
      // Suspend any user deployed jar file updates during this backup.
      deployer = getJarDeployer();
      deployer.suspendAll();

      List<DeployedJar> jarList = deployer.findDeployedJars();
      for (DeployedJar jar : jarList) {
        File source = new File(jar.getFileCanonicalPath());
        String sourceFileName = source.getName();
        Path destination = userDirectory.resolve(sourceFileName);
        Files.copy(source.toPath(), destination, StandardCopyOption.COPY_ATTRIBUTES);
        backupDefinition.addDeployedJarToBackup(destination, source.toPath());
        userJars.add(source);
      }
    } finally {
      // Re-enable user deployed jar file updates.
      if (deployer != null) {
        deployer.resumeAll();
      }
    }
    return userJars;
  }

  void copyDiskInitFile(DiskStoreImpl diskStore) throws IOException {
    File diskInitFile = diskStore.getDiskInitFile().getIFFile();
    String subDirName = Integer.toString(diskStore.getInforFileDirIndex());
    Path subDir = temporaryFiles.getDirectory().resolve(subDirName);
    Files.createDirectories(subDir);
    Files.copy(diskInitFile.toPath(), subDir.resolve(diskInitFile.getName()),
        StandardCopyOption.COPY_ATTRIBUTES);
    backupDefinition.addDiskInitFile(diskStore, subDir.resolve(diskInitFile.getName()));
  }

  void copyOplog(DiskStore diskStore, Oplog oplog) throws IOException {
    DirectoryHolder dirHolder = oplog.getDirectoryHolder();
    copyOplogFile(diskStore, dirHolder, oplog.getCrfFile());
    copyOplogFile(diskStore, dirHolder, oplog.getDrfFile());
    copyOplogFile(diskStore, dirHolder, oplog.getKrfFile());
  }

  private void copyOplogFile(DiskStore diskStore, DirectoryHolder dirHolder, File file)
      throws IOException {
    if (file == null || !file.exists()) {
      return;
    }

    Path tempDiskDir = temporaryFiles.getDiskStoreDirectory(diskStore, dirHolder);
    if (!SystemUtils.isWindows()) {
      try {
        createLink(tempDiskDir.resolve(file.getName()), file.toPath());
      } catch (IOException e) {
        logger.warn("Unable to create hard link for {}. Reverting to file copy",
            tempDiskDir.toString());
        FileUtils.copyFileToDirectory(file, tempDiskDir.toFile());
      }
    } else {
      // Hard links cannot be deleted on Windows if the process is still running, so prefer to
      // actually copy the files.
      FileUtils.copyFileToDirectory(file, tempDiskDir.toFile());
    }

    backupDefinition.addOplogFileToBackup(diskStore, tempDiskDir.resolve(file.getName()));
  }

  JarDeployer getJarDeployer() {
    return ClassPathLoader.getLatest().getJarDeployer();
  }

  void createLink(Path link, Path existing) throws IOException {
    Files.createLink(link, existing);
  }

  Path getSource(URL fileUrl) throws URISyntaxException {
    return Paths.get(fileUrl.toURI());
  }
}
