use std::ffi::OsString;
use std::path::PathBuf;
use std::process::Command;

use itertools::Itertools;
use rustc_errors::msg;
use rustc_middle::middle::exported_symbols::SymbolExportKind;
use rustc_session::Session;
pub(super) use rustc_target::spec::apple::OSVersion;
use rustc_target::spec::{Arch, Env, Os, Target};
use tracing::debug;

use crate::errors::{XcrunError, XcrunSdkPathWarning};

#[cfg(test)]
mod tests;

/// The canonical name of the desired SDK for a given target.
pub(super) fn sdk_name(target: &Target) -> &'static str {
    match (&target.os, &target.env) {
        (Os::MacOs, Env::Unspecified) => "MacOSX",
        (Os::IOs, Env::Unspecified) => "iPhoneOS",
        (Os::IOs, Env::Sim) => "iPhoneSimulator",
        // Mac Catalyst uses the macOS SDK
        (Os::IOs, Env::MacAbi) => "MacOSX",
        (Os::TvOs, Env::Unspecified) => "AppleTVOS",
        (Os::TvOs, Env::Sim) => "AppleTVSimulator",
        (Os::VisionOs, Env::Unspecified) => "XROS",
        (Os::VisionOs, Env::Sim) => "XRSimulator",
        (Os::WatchOs, Env::Unspecified) => "WatchOS",
        (Os::WatchOs, Env::Sim) => "WatchSimulator",
        (os, abi) => unreachable!("invalid os '{os}' / abi '{abi}' combination for Apple target"),
    }
}

pub(super) fn macho_platform(target: &Target) -> u32 {
    match (&target.os, &target.env) {
        (Os::MacOs, _) => object::macho::PLATFORM_MACOS,
        (Os::IOs, Env::MacAbi) => object::macho::PLATFORM_MACCATALYST,
        (Os::IOs, Env::Sim) => object::macho::PLATFORM_IOSSIMULATOR,
        (Os::IOs, _) => object::macho::PLATFORM_IOS,
        (Os::WatchOs, Env::Sim) => object::macho::PLATFORM_WATCHOSSIMULATOR,
        (Os::WatchOs, _) => object::macho::PLATFORM_WATCHOS,
        (Os::TvOs, Env::Sim) => object::macho::PLATFORM_TVOSSIMULATOR,
        (Os::TvOs, _) => object::macho::PLATFORM_TVOS,
        (Os::VisionOs, Env::Sim) => object::macho::PLATFORM_XROSSIMULATOR,
        (Os::VisionOs, _) => object::macho::PLATFORM_XROS,
        (os, env) => unreachable!("invalid os '{os}' / env '{env}' combination for Apple target"),
    }
}

/// Add relocation and section data needed for a symbol to be considered
/// undefined by ld64.
///
/// The relocation must be valid, and hence must point to a valid piece of
/// machine code, and hence this is unfortunately very architecture-specific.
///
///
/// # New architectures
///
/// The values here are basically the same as emitted by the following program:
///
/// ```c
/// // clang -c foo.c -target $CLANG_TARGET
/// void foo(void);
///
/// extern int bar;
///
/// void* foobar[2] = {
///     (void*)foo,
///     (void*)&bar,
///     // ...
/// };
/// ```
///
/// Can be inspected with:
/// ```console
/// objdump --macho --reloc foo.o
/// objdump --macho --full-contents foo.o
/// ```
pub(super) fn add_data_and_relocation(
    file: &mut object::write::Object<'_>,
    section: object::write::SectionId,
    symbol: object::write::SymbolId,
    target: &Target,
    kind: SymbolExportKind,
) -> object::write::Result<()> {
    let authenticated_pointer =
        kind == SymbolExportKind::Text && target.llvm_target.starts_with("arm64e");

    let data: &[u8] = match target.pointer_width {
        _ if authenticated_pointer => &[0, 0, 0, 0, 0, 0, 0, 0x80],
        32 => &[0; 4],
        64 => &[0; 8],
        pointer_width => unimplemented!("unsupported Apple pointer width {pointer_width:?}"),
    };

    if target.arch == Arch::X86_64 {
        // Force alignment for the entire section to be 16 on x86_64.
        file.section_mut(section).append_data(&[], 16);
    } else {
        // Elsewhere, the section alignment is the same as the pointer width.
        file.section_mut(section).append_data(&[], target.pointer_width as u64);
    }

    let offset = file.section_mut(section).append_data(data, data.len() as u64);

    let flags = if authenticated_pointer {
        object::write::RelocationFlags::MachO {
            r_type: object::macho::ARM64_RELOC_AUTHENTICATED_POINTER,
            r_pcrel: false,
            r_length: 3,
        }
    } else if target.arch == Arch::Arm {
        // FIXME(madsmtm): Remove once `object` supports 32-bit ARM relocations:
        // https://github.com/gimli-rs/object/pull/757
        object::write::RelocationFlags::MachO {
            r_type: object::macho::ARM_RELOC_VANILLA,
            r_pcrel: false,
            r_length: 2,
        }
    } else {
        object::write::RelocationFlags::Generic {
            kind: object::RelocationKind::Absolute,
            encoding: object::RelocationEncoding::Generic,
            size: target.pointer_width as u8,
        }
    };

    file.add_relocation(section, object::write::Relocation { offset, addend: 0, symbol, flags })?;

    Ok(())
}

pub(super) fn add_version_to_llvm_target(
    llvm_target: &str,
    deployment_target: OSVersion,
) -> String {
    let mut components = llvm_target.split("-");
    let arch = components.next().expect("apple target should have arch");
    let vendor = components.next().expect("apple target should have vendor");
    let os = components.next().expect("apple target should have os");
    let environment = components.next();
    assert_eq!(components.next(), None, "too many LLVM triple components");

    assert!(
        !os.contains(|c: char| c.is_ascii_digit()),
        "LLVM target must not already be versioned"
    );

    let version = deployment_target.fmt_full();
    if let Some(env) = environment {
        // Insert version into OS, before environment
        format!("{arch}-{vendor}-{os}{version}-{env}")
    } else {
        format!("{arch}-{vendor}-{os}{version}")
    }
}

pub(super) fn get_sdk_root(sess: &Session) -> Option<PathBuf> {
    let sdk_name = sdk_name(&sess.target);

    // Attempt to invoke `xcrun` to find the SDK.
    //
    // Note that when cross-compiling from e.g. Linux, the `xcrun` binary may sometimes be provided
    // as a shim by a cross-compilation helper tool. It usually isn't, but we still try nonetheless.
    match xcrun_show_sdk_path(sdk_name, false) {
        Ok((path, stderr)) => {
            // Emit extra stderr, such as if `-verbose` was passed, or if `xcrun` emitted a warning.
            if !stderr.is_empty() {
                sess.dcx().emit_warn(XcrunSdkPathWarning { sdk_name, stderr });
            }
            Some(path)
        }
        Err(err) => {
            // Failure to find the SDK is not a hard error, since the user might have specified it
            // in a manner unknown to us (moreso if cross-compiling):
            // - A compiler driver like `zig cc` which links using an internally bundled SDK.
            // - Extra linker arguments (`-Clink-arg=-syslibroot`).
            // - A custom linker or custom compiler driver.
            //
            // Though we still warn, since such cases are uncommon, and it is very hard to debug if
            // you do not know the details.
            //
            // FIXME(madsmtm): Make this a lint, to allow deny warnings to work.
            // (Or fix <https://github.com/rust-lang/rust/issues/21204>).
            let mut diag = sess.dcx().create_warn(err);
            diag.note(msg!("the SDK is needed by the linker to know where to find symbols in system libraries and for embedding the SDK version in the final object file"));

            // Recognize common error cases, and give more Rust-specific error messages for those.
            if let Some(developer_dir) = xcode_select_developer_dir() {
                diag.arg("developer_dir", &developer_dir);
                diag.note(msg!("found active developer directory at \"{$developer_dir}\""));
                if developer_dir.as_os_str().to_string_lossy().contains("CommandLineTools") {
                    if sdk_name != "MacOSX" {
                        diag.help(msg!("when compiling for iOS, tvOS, visionOS or watchOS, you need a full installation of Xcode"));
                    }
                }
            } else {
                diag.help(msg!("pass the path of an Xcode installation via the DEVELOPER_DIR environment variable, or an SDK with the SDKROOT environment variable"));
            }

            diag.emit();
            None
        }
    }
}

/// Invoke `xcrun --sdk $sdk_name --show-sdk-path` to get the SDK path.
///
/// The exact logic that `xcrun` uses is unspecified (see `man xcrun` for a few details), and may
/// change between macOS and Xcode versions, but it roughly boils down to finding the active
/// developer directory, and then invoking `xcodebuild -sdk $sdk_name -version` to get the SDK
/// details.
///
/// Finding the developer directory is roughly done by looking at, in order:
/// - The `DEVELOPER_DIR` environment variable.
/// - The `/var/db/xcode_select_link` symlink (set by `xcode-select --switch`).
/// - `/Applications/Xcode.app` (hardcoded fallback path).
/// - `/Library/Developer/CommandLineTools` (hardcoded fallback path).
///
/// Note that `xcrun` caches its result, but with a cold cache this whole operation can be quite
/// slow, especially so the first time it's run after a reboot.
fn xcrun_show_sdk_path(
    sdk_name: &'static str,
    verbose: bool,
) -> Result<(PathBuf, String), XcrunError> {
    // Intentionally invoke the `xcrun` in PATH, since e.g. nixpkgs provide an `xcrun` shim, so we
    // don't want to require `/usr/bin/xcrun`.
    let mut cmd = Command::new("xcrun");
    if verbose {
        cmd.arg("--verbose");
    }
    // The `--sdk` parameter is the same as in xcodebuild, namely either an absolute path to an SDK,
    // or the (lowercase) canonical name of an SDK.
    cmd.arg("--sdk");
    cmd.arg(&sdk_name.to_lowercase());
    cmd.arg("--show-sdk-path");

    // We do not stream stdout/stderr lines directly to the user, since whether they are warnings or
    // errors depends on the status code at the end.
    let output = cmd.output().map_err(|error| XcrunError::FailedInvoking {
        sdk_name,
        command_formatted: format!("{cmd:?}"),
        error,
    })?;

    // It is fine to do lossy conversion here, non-UTF-8 paths are quite rare on macOS nowadays
    // (only possible with the HFS+ file system), and we only use it for error messages.
    let stderr = String::from_utf8_lossy_owned(output.stderr);
    if !stderr.is_empty() {
        debug!(stderr, "original xcrun stderr");
    }

    // Some versions of `xcodebuild` output beefy errors when invoked via `xcrun`,
    // but these are usually red herrings.
    let stderr = stderr
        .lines()
        .filter(|line| {
            !line.contains("Writing error result bundle")
                && !line.contains("Requested but did not find extension point with identifier")
        })
        .join("\n");

    if output.status.success() {
        Ok((stdout_to_path(output.stdout), stderr))
    } else {
        // Output both stdout and stderr, since shims of `xcrun` (such as the one provided by
        // nixpkgs), do not always use stderr for errors.
        let stdout = String::from_utf8_lossy_owned(output.stdout).trim().to_string();
        Err(XcrunError::Unsuccessful {
            sdk_name,
            command_formatted: format!("{cmd:?}"),
            stdout,
            stderr,
        })
    }
}

/// Invoke `xcode-select --print-path`, and return the current developer directory.
///
/// NOTE: We don't do any error handling here, this is only used as a canary in diagnostics (`xcrun`
/// will have already emitted the relevant error information).
fn xcode_select_developer_dir() -> Option<PathBuf> {
    let mut cmd = Command::new("xcode-select");
    cmd.arg("--print-path");
    let output = cmd.output().ok()?;
    if !output.status.success() {
        return None;
    }
    Some(stdout_to_path(output.stdout))
}

fn stdout_to_path(mut stdout: Vec<u8>) -> PathBuf {
    // Remove trailing newline.
    if let Some(b'\n') = stdout.last() {
        let _ = stdout.pop().unwrap();
    }
    #[cfg(unix)]
    let path = <OsString as std::os::unix::ffi::OsStringExt>::from_vec(stdout);
    #[cfg(not(unix))] // Not so important, this is mostly used on macOS
    let path = OsString::from(String::from_utf8(stdout).expect("stdout must be UTF-8"));
    PathBuf::from(path)
}
