// Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use std::collections::HashSet;
use std::env;
use std::path::{Path, PathBuf};
use std::fs;
use syntax::ast;

pub struct RPathConfig<'a> {
    pub used_crates: Vec<(ast::CrateNum, Option<PathBuf>)>,
    pub out_filename: PathBuf,
    pub is_like_osx: bool,
    pub has_rpath: bool,
    pub linker_is_gnu: bool,
    pub get_install_prefix_lib_path: &'a mut FnMut() -> PathBuf,
}

pub fn get_rpath_flags(config: &mut RPathConfig) -> Vec<String> {
    // No rpath on windows
    if !config.has_rpath {
        return Vec::new();
    }

    let mut flags = Vec::new();

    debug!("preparing the RPATH!");

    let libs = config.used_crates.clone();
    let libs = libs.into_iter().filter_map(|(_, l)| l).collect::<Vec<_>>();
    let rpaths = get_rpaths(config, &libs[..]);
    flags.extend_from_slice(&rpaths_to_flags(&rpaths[..]));

    // Use DT_RUNPATH instead of DT_RPATH if available
    if config.linker_is_gnu {
        flags.push("-Wl,--enable-new-dtags".to_string());
    }

    flags
}

fn rpaths_to_flags(rpaths: &[String]) -> Vec<String> {
    let mut ret = Vec::new();
    for rpath in rpaths {
        ret.push(format!("-Wl,-rpath,{}", &(*rpath)));
    }
    return ret;
}

fn get_rpaths(config: &mut RPathConfig, libs: &[PathBuf]) -> Vec<String> {
    debug!("output: {:?}", config.out_filename.display());
    debug!("libs:");
    for libpath in libs {
        debug!("    {:?}", libpath.display());
    }

    // Use relative paths to the libraries. Binaries can be moved
    // as long as they maintain the relative relationship to the
    // crates they depend on.
    let rel_rpaths = get_rpaths_relative_to_output(config, libs);

    // And a final backup rpath to the global library location.
    let fallback_rpaths = vec!(get_install_prefix_rpath(config));

    fn log_rpaths(desc: &str, rpaths: &[String]) {
        debug!("{} rpaths:", desc);
        for rpath in rpaths {
            debug!("    {}", *rpath);
        }
    }

    log_rpaths("relative", &rel_rpaths[..]);
    log_rpaths("fallback", &fallback_rpaths[..]);

    let mut rpaths = rel_rpaths;
    rpaths.extend_from_slice(&fallback_rpaths[..]);

    // Remove duplicates
    let rpaths = minimize_rpaths(&rpaths[..]);
    return rpaths;
}

fn get_rpaths_relative_to_output(config: &mut RPathConfig,
                                 libs: &[PathBuf]) -> Vec<String> {
    libs.iter().map(|a| get_rpath_relative_to_output(config, a)).collect()
}

fn get_rpath_relative_to_output(config: &mut RPathConfig, lib: &Path) -> String {
    // Mac doesn't appear to support $ORIGIN
    let prefix = if config.is_like_osx {
        "@loader_path"
    } else {
        "$ORIGIN"
    };

    let cwd = env::current_dir().unwrap();
    let mut lib = fs::canonicalize(&cwd.join(lib)).unwrap_or(cwd.join(lib));
    lib.pop();
    let mut output = cwd.join(&config.out_filename);
    output.pop();
    let output = fs::canonicalize(&output).unwrap_or(output);
    let relative = path_relative_from(&lib, &output)
        .expect(&format!("couldn't create relative path from {:?} to {:?}", output, lib));
    // FIXME (#9639): This needs to handle non-utf8 paths
    format!("{}/{}", prefix,
            relative.to_str().expect("non-utf8 component in path"))
}

// This routine is adapted from the *old* Path's `path_relative_from`
// function, which works differently from the new `relative_from` function.
// In particular, this handles the case on unix where both paths are
// absolute but with only the root as the common directory.
fn path_relative_from(path: &Path, base: &Path) -> Option<PathBuf> {
    use std::path::Component;

    if path.is_absolute() != base.is_absolute() {
        if path.is_absolute() {
            Some(PathBuf::from(path))
        } else {
            None
        }
    } else {
        let mut ita = path.components();
        let mut itb = base.components();
        let mut comps: Vec<Component> = vec![];
        loop {
            match (ita.next(), itb.next()) {
                (None, None) => break,
                (Some(a), None) => {
                    comps.push(a);
                    comps.extend(ita.by_ref());
                    break;
                }
                (None, _) => comps.push(Component::ParentDir),
                (Some(a), Some(b)) if comps.is_empty() && a == b => (),
                (Some(a), Some(b)) if b == Component::CurDir => comps.push(a),
                (Some(_), Some(b)) if b == Component::ParentDir => return None,
                (Some(a), Some(_)) => {
                    comps.push(Component::ParentDir);
                    for _ in itb {
                        comps.push(Component::ParentDir);
                    }
                    comps.push(a);
                    comps.extend(ita.by_ref());
                    break;
                }
            }
        }
        Some(comps.iter().map(|c| c.as_os_str()).collect())
    }
}


fn get_install_prefix_rpath(config: &mut RPathConfig) -> String {
    let path = (config.get_install_prefix_lib_path)();
    let path = env::current_dir().unwrap().join(&path);
    // FIXME (#9639): This needs to handle non-utf8 paths
    path.to_str().expect("non-utf8 component in rpath").to_string()
}

fn minimize_rpaths(rpaths: &[String]) -> Vec<String> {
    let mut set = HashSet::new();
    let mut minimized = Vec::new();
    for rpath in rpaths {
        if set.insert(&rpath[..]) {
            minimized.push(rpath.clone());
        }
    }
    minimized
}

#[cfg(all(unix, test))]
mod tests {
    use super::{RPathConfig};
    use super::{minimize_rpaths, rpaths_to_flags, get_rpath_relative_to_output};
    use std::path::{Path, PathBuf};

    #[test]
    fn test_rpaths_to_flags() {
        let flags = rpaths_to_flags(&[
            "path1".to_string(),
            "path2".to_string()
        ]);
        assert_eq!(flags,
                   ["-Wl,-rpath,path1",
                    "-Wl,-rpath,path2"]);
    }

    #[test]
    fn test_minimize1() {
        let res = minimize_rpaths(&[
            "rpath1".to_string(),
            "rpath2".to_string(),
            "rpath1".to_string()
        ]);
        assert!(res == [
            "rpath1",
            "rpath2",
        ]);
    }

    #[test]
    fn test_minimize2() {
        let res = minimize_rpaths(&[
            "1a".to_string(),
            "2".to_string(),
            "2".to_string(),
            "1a".to_string(),
            "4a".to_string(),
            "1a".to_string(),
            "2".to_string(),
            "3".to_string(),
            "4a".to_string(),
            "3".to_string()
        ]);
        assert!(res == [
            "1a",
            "2",
            "4a",
            "3",
        ]);
    }

    #[test]
    fn test_rpath_relative() {
        if cfg!(target_os = "macos") {
            let config = &mut RPathConfig {
                used_crates: Vec::new(),
                has_rpath: true,
                is_like_osx: true,
                linker_is_gnu: false,
                out_filename: PathBuf::from("bin/rustc"),
                get_install_prefix_lib_path: &mut || panic!(),
            };
            let res = get_rpath_relative_to_output(config,
                                                   Path::new("lib/libstd.so"));
            assert_eq!(res, "@loader_path/../lib");
        } else {
            let config = &mut RPathConfig {
                used_crates: Vec::new(),
                out_filename: PathBuf::from("bin/rustc"),
                get_install_prefix_lib_path: &mut || panic!(),
                has_rpath: true,
                is_like_osx: false,
                linker_is_gnu: true,
            };
            let res = get_rpath_relative_to_output(config,
                                                   Path::new("lib/libstd.so"));
            assert_eq!(res, "$ORIGIN/../lib");
        }
    }
}
