/*
 * 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.internal.logging.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());
  }
}
