// Copyright 2023 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

//! This module provides a way to copy files preferentially using hardlinks, and
//! will fall back to a slow copy if that fails.

use anyhow::{Context, Result};
use std::path::Path;

/// Copy a file from `src` to `dst`, using hardlinks if possible, and silently
/// falling back to a "slow" copy (using `std::fs::copy()`) if the hardlink
/// fails to be created.
pub fn fast_copy(src: impl AsRef<Path>, dst: impl AsRef<Path>) -> Result<()> {
    let src = src.as_ref();
    let dst = dst.as_ref();

    // Defer to a function that doesn't need to be monomorphized.
    fast_copy_impl(src, dst)
}

/// An internal helper method that doesn't use generics
fn fast_copy_impl(src: &Path, dst: &Path) -> Result<()> {
    // Get the actual src file, if it exists, as 'hard_link' and 'copy' won't
    // follow symlinks, but copy the symlink itself (which isn't our goal)
    let real_path = src
        .canonicalize()
        .with_context(|| format!("getting the real path for: {}", src.display()))?;

    if let Some(parent) = dst.parent() {
        std::fs::create_dir_all(parent)
            .with_context(|| format!("creating parent directories for {}: ", dst.display()))?;
    }

    // Perform a hardlink if possible
    std::fs::hard_link(&real_path, dst).or_else(|_| {
        // falling back to a slow copy if it can't be copied.
        std::fs::copy(&real_path, dst)
            .map(|_| ())
            .with_context(|| format!("copying {} to {}", src.display(), dst.display()))
    })
}

#[cfg(test)]
mod tests {
    use super::*;
    use tempfile::TempDir;

    #[test]
    fn test_simple_copy() {
        let temp_dir = TempDir::new().unwrap();
        let src = temp_dir.path().join("src.txt");
        let dst = temp_dir.path().join("dst.txt");

        std::fs::write(&src, "some text").unwrap();

        fast_copy(src, &dst).unwrap();

        let dst_contents = std::fs::read(dst).unwrap();
        let dst_string = String::from_utf8(dst_contents).unwrap();

        assert_eq!(dst_string, "some text");
    }

    #[test]
    fn test_missing_source_fails() {
        let temp_dir = TempDir::new().unwrap();
        let src = temp_dir.path().join("src.txt");
        let dst = temp_dir.path().join("dst.txt");

        let result = fast_copy(src, &dst);
        assert!(result.is_err());
    }

    #[test]
    fn test_creates_parents_of_dest() {
        let temp_dir = TempDir::new().unwrap();
        let src = temp_dir.path().join("src.txt");
        let dst = temp_dir.path().join("some/nonexistent/parent/dst.txt");

        std::fs::write(&src, "some text").unwrap();

        fast_copy(src, &dst).unwrap();

        let dst_contents = std::fs::read(dst).unwrap();
        let dst_string = String::from_utf8(dst_contents).unwrap();

        assert_eq!(dst_string, "some text");
    }
}

#[cfg(test)]
#[cfg(target_family = "unix")]
mod tests_unix {
    use super::*;
    use std::os::unix::fs::MetadataExt;
    use tempfile::TempDir;

    #[test]
    fn test_copy_is_hardlink() {
        let temp_dir = TempDir::new().unwrap();
        let src = temp_dir.path().join("src.txt");
        let dst = temp_dir.path().join("dst.txt");

        std::fs::write(&src, "some text").unwrap();

        fast_copy(&src, &dst).unwrap();

        let dst_contents = std::fs::read(&dst).unwrap();
        let dst_string = String::from_utf8(dst_contents).unwrap();

        assert_eq!(dst_string, "some text");

        let src_metadata = std::fs::metadata(&src).unwrap();
        let dst_metadata = std::fs::metadata(&dst).unwrap();

        assert_eq!(
            src_metadata.ino(),
            dst_metadata.ino(),
            "src and dst files have different inodes"
        )
    }

    #[test]
    fn test_copy_through_symlink_is_hardlink() {
        let temp_dir = TempDir::new().unwrap();
        let src = temp_dir.path().join("src.txt");
        let symlink = temp_dir.path().join("symlink.txt");
        let dst = temp_dir.path().join("dst.txt");

        std::fs::write(&src, "some text").unwrap();

        std::os::unix::fs::symlink(&src, &symlink).unwrap();

        fast_copy(&symlink, &dst).unwrap();

        let dst_contents = std::fs::read(&dst).unwrap();
        let dst_string = String::from_utf8(dst_contents).unwrap();

        assert_eq!(dst_string, "some text");

        // Validate that it copied the source file, not the symlink.  This is after
        // the contents have been validated to ensure that the file actually exists,
        // as this will return false if the file doesn't exist.
        assert!(!dst.is_symlink());

        // Validate that the dst file is a hardlink to the src file, as they should
        // have the same inode if they are hardlinks to the same file.
        let src_metadata = std::fs::metadata(&src).unwrap();
        let dst_metadata = std::fs::metadata(&dst).unwrap();
        assert_eq!(
            src_metadata.ino(),
            dst_metadata.ino(),
            "src and dst files have different inodes"
        )
    }

    #[test]
    fn test_copy_through_broken_symlink_fails() {
        let temp_dir = TempDir::new().unwrap();
        let src = temp_dir.path().join("src.txt");
        let symlink = temp_dir.path().join("symlink.txt");
        let dst = temp_dir.path().join("dst.txt");

        std::os::unix::fs::symlink(&src, &symlink).unwrap();

        let result = fast_copy(&symlink, &dst);
        assert!(result.is_err());
    }
}
