// Copyright 2020 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.

use crate::args::StartCommand;
use crate::cipd;
use ansi_term::Colour::*;
use anyhow::{anyhow, format_err, Result};
use fuchsia_async::Executor;
use home::home_dir;
use hyper::{StatusCode, Uri};
use std::convert::From;
use std::env;
use std::fs::{create_dir, create_dir_all, read_to_string, remove_dir_all, remove_file, File};
use std::io::{BufRead, BufReader};
use std::os::unix;
use std::path::PathBuf;

pub fn read_env_path(var: &str) -> Result<PathBuf> {
    env::var_os(var).map(PathBuf::from).ok_or(anyhow!("{} contained invalid Unicode", var))
}

/// Returns GN SDK tools directory. This assumes that fvdl is located in
/// <sdk_root>/tools/[x64|arm64]/fvdl, and will return path to <sdk_root>/tools/[x64|arm64]
pub fn get_fuchsia_sdk_tools_dir() -> Result<PathBuf> {
    Ok(env::args_os()
        .nth(0)
        .map(PathBuf::from)
        .ok_or(anyhow!("Cannot get invoking binary path (location of fvdl)."))?
        .parent()
        .ok_or(anyhow!("Cannot get parent path to 'fvdl'."))?
        .to_path_buf())
}

/// Returns GN SDK tools directory. This assumes that fvdl is located in
/// <sdk_root>/tools/[x64|arm64]/fvdl, and will return path to <sdk_root>
pub fn get_fuchsia_sdk_dir() -> Result<PathBuf> {
    Ok(get_fuchsia_sdk_tools_dir()? // ex: <sdk_root>/tools/x64/
        .parent() // ex: <sdk_root>/tools/
        .ok_or(anyhow!("Cannot get parent path to 'tools' directory."))?
        .parent() // ex: <sdk_root>
        .ok_or(anyhow!("Cannot get path to sdk root."))?
        .to_path_buf())
}

/// Returns either the path specified in the environment variable FUCHSIA_SDK_DATA_DIR or
/// $HOME/.fuchsia
pub fn get_sdk_data_dir() -> Result<PathBuf> {
    let sdk_data_dir = match read_env_path("FUCHSIA_SDK_DATA_DIR") {
        Ok(dir) => dir,
        _ => {
            let default = home_dir().unwrap_or_default().join(".fuchsia");
            if !default.exists() {
                create_dir(&default)?;
            }
            default
        }
    };
    Ok(sdk_data_dir)
}

pub struct HostTools {
    pub aemu: PathBuf,
    pub device_finder: PathBuf,
    pub far: PathBuf,
    pub fvm: PathBuf,
    pub grpcwebproxy: PathBuf,
    pub pm: PathBuf,
    pub vdl: PathBuf,
    pub zbi: PathBuf,
    pub is_sdk: bool,
}

impl HostTools {
    /// Initialize host tools for in-tree usage.
    ///
    /// Requires the environment variable HOST_OUT_DIR to be specified
    /// PREBUILT_AEMU_DIR, PREBUILT_GRPCWEBPROXY_DIR, PREBUILT_VDL_DIR are optional.
    /// See: //tools/devshell/vdl
    pub fn from_tree_env() -> Result<HostTools> {
        let host_out_dir = read_env_path("HOST_OUT_DIR")?;
        Ok(HostTools {
            // prebuilt binaries that can be optionally fetched from cipd.
            aemu: match read_env_path("PREBUILT_AEMU_DIR") {
                Ok(val) => val.join("emulator"),
                _ => PathBuf::new(),
            },
            grpcwebproxy: match read_env_path("PREBUILT_GRPCWEBPROXY_DIR") {
                Ok(val) => val.join("grpcwebproxy"),
                _ => PathBuf::new(),
            },
            vdl: match read_env_path("PREBUILT_VDL_DIR") {
                Ok(val) => val.join("device_launcher"),
                _ => PathBuf::new(),
            },
            device_finder: host_out_dir.join("device-finder"),
            far: host_out_dir.join("far"),
            fvm: host_out_dir.join("fvm"),
            pm: host_out_dir.join("pm"),
            zbi: host_out_dir.join("zbi"),
            is_sdk: false,
        })
    }

    /// Initialize host tools for GN SDK usage.
    ///
    /// First check the existence of environment variable TOOL_DIR, if not specified
    /// look for host tools in the program's containing directory.
    pub fn from_sdk_env() -> Result<HostTools> {
        let sdk_tool_dir = match read_env_path("TOOL_DIR") {
            Ok(dir) => dir,
            _ => get_fuchsia_sdk_tools_dir()?,
        };

        Ok(HostTools {
            // prebuilt binaries that can be optionally fetched from cipd.
            aemu: PathBuf::new(),
            grpcwebproxy: PathBuf::new(),
            vdl: PathBuf::new(),
            // in-tree tools that are packaged with GN SDK.
            device_finder: sdk_tool_dir.join("device-finder"),
            far: sdk_tool_dir.join("far"),
            fvm: sdk_tool_dir.join("fvm"),
            pm: sdk_tool_dir.join("pm"),
            zbi: sdk_tool_dir.join("zbi"),
            is_sdk: true,
        })
    }

    /// Reads the <prebuild>.version file stored in <sdk_root>/bin/<prebuild>.version
    ///
    /// # Arguments
    ///
    /// * `file_name` - <prebuild>.version file name.
    ///     ex: 'aemu.version', this file is expected to be found under <sdk_root>/bin
    pub fn read_prebuild_version(&self, file_name: &str) -> Result<String> {
        if self.is_sdk {
            let version_file = get_fuchsia_sdk_dir()?.join("bin").join(file_name);
            if version_file.exists() {
                println!(
                    "{}",
                    Yellow.paint(format!(
                        "[fvdl] reading prebuild version file from: {}",
                        version_file.display()
                    ))
                );
                return Ok(read_to_string(version_file)?);
            };
            println!(
                "{}",
                Red.paint(format!(
                    "[fvdl] prebuild version file: {} does not exist.",
                    version_file.display()
                ))
            );
            return Err(format_err!(
                "reading prebuilt version errored: file {:?} does not exist.",
                version_file
            ));
        }
        return Err(format_err!("reading prebuild version file is only support with --sdk flag."));
    }

    /// Downloads & extract aemu.zip from CIPD, and returns the path containing the emulator executable.
    ///
    /// # Arguments
    ///
    /// * `label` - cipd label that specified a particular aemu version
    /// * `cipd_pkg` - this is appeneded to cipd url https://chrome-infra-packages.appspot.com/dl/fuchsia/third_party/.
    pub fn download_and_extract(&self, label: String, cipd_pkg: String) -> Result<PathBuf> {
        let mut executor = Executor::new().unwrap();
        executor.run_singlethreaded(async move {
            let root_path = match read_env_path("FEMU_DOWNLOAD_DIR") {
                Ok(path) => path,
                _ => {
                    let default_path = get_sdk_data_dir()?.join("femu");
                    if !default_path.exists() {
                        create_dir_all(&default_path)?;
                    }
                    default_path
                }
            };
            let arch = match env::consts::OS {
                "macos" => "mac-amd64",
                _ => "linux-amd64",
            };
            let url = format!(
                "https://chrome-infra-packages.appspot.com/dl/fuchsia/{}/{}/+/{}",
                cipd_pkg, arch, label
            )
            .parse::<Uri>()?;
            let name = cipd_pkg
                .split('/')
                .last()
                .ok_or(anyhow!("Cannot identify filename from {}", cipd_pkg))?;
            let cipd_zip = root_path.join(format!("{}-{}.zip", name, label.replace(":", "-")));
            let unzipped_root = root_path.join(format!("{}-{}", name, label.replace(":", "-")));

            match label.as_str() {
                // "latest" and "integration" labels always point to the newest release.
                // We cannot assume that the binary is the same as last fetched. Therefore
                // we will always re-download and unzip when used.
                "latest" | "integration" => {
                    if cipd_zip.exists() {
                        remove_file(&cipd_zip)?;
                    }
                    if unzipped_root.exists() {
                        remove_dir_all(&unzipped_root)?;
                    }
                }
                _ => {
                    if unzipped_root.exists() {
                        return Ok(unzipped_root);
                    }
                }
            };
            let status = cipd::download(url.clone(), &cipd_zip).await?;
            if status == StatusCode::OK {
                cipd::extract_zip(&cipd_zip, &unzipped_root)?;
                Ok(unzipped_root)
            } else {
                Err(format_err!(
                    "Cannot download file from cipd path {}. Got status code {}",
                    url,
                    status.as_str(),
                ))
            }
        })
    }
}

pub struct ImageFiles {
    pub amber_files: PathBuf,
    pub build_args: PathBuf,
    pub fvm: PathBuf,
    pub kernel: PathBuf,
    pub zbi: PathBuf,
}

impl ImageFiles {
    /// Initialize fuchsia image and package files for in-tree usage.
    ///
    /// Requires the environment variable FUCHSIA_BUILD_DIR to be specified.
    pub fn from_tree_env() -> Result<ImageFiles> {
        let fuchsia_build_dir = read_env_path("FUCHSIA_BUILD_DIR")?;
        Ok(ImageFiles {
            amber_files: fuchsia_build_dir.join("amber-files"),
            build_args: fuchsia_build_dir.join("args.gn"),
            fvm: fuchsia_build_dir.join(read_env_path("IMAGE_FVM_RAW")?),
            kernel: fuchsia_build_dir.join(read_env_path("IMAGE_QEMU_KERNEL_RAW")?),
            zbi: fuchsia_build_dir.join(read_env_path("IMAGE_ZIRCONA_ZBI")?),
        })
    }

    /// Initialize fuchsia image and package files for GN SDK usage.
    ///
    /// First check the existence of environment variable IMAGE_DIR, if not specified
    /// make a best effort guess in other known paths by calling get_sdk_data_dir().
    ///
    /// If --sdk_version is specified, fuchsia image will be downloaded from GCS.
    pub fn from_sdk_env() -> Result<ImageFiles> {
        let fuchsia_build_dir = match read_env_path("IMAGE_DIR") {
            Ok(dir) => dir,
            _ => get_sdk_data_dir()?,
        };
        Ok(ImageFiles {
            amber_files: fuchsia_build_dir.join("amber-files"),
            build_args: fuchsia_build_dir.join("buildargs.gn"),
            fvm: fuchsia_build_dir.join("storage-full.blk"),
            kernel: fuchsia_build_dir.join("femu-kernel.kernel"),
            zbi: fuchsia_build_dir.join("zircon-a.zbi"),
        })
    }

    pub fn stage_files(&mut self, dir: &PathBuf) -> Result<()> {
        let vdl_kernel_dest = dir.join("femu_kernel");
        let vdl_kernel_src = self.kernel.as_path();
        unix::fs::symlink(&vdl_kernel_src, &vdl_kernel_dest)?;
        self.kernel = vdl_kernel_dest.to_path_buf();

        let vdl_fvm_dest = dir.join("femu_fvm");
        let vdl_fvm_src = self.fvm.as_path();
        unix::fs::symlink(&vdl_fvm_src, &vdl_fvm_dest)?;
        self.fvm = vdl_fvm_dest.to_path_buf();

        let vdl_args_dest = dir.join("femu_buildargs");
        let vdl_args_src = self.build_args.as_path();
        unix::fs::symlink(&vdl_args_src, &vdl_args_dest)?;
        self.build_args = vdl_args_dest.to_path_buf();
        Ok(())
    }
}

pub struct SSHKeys {
    pub auth_key: PathBuf,
    pub private_key: PathBuf,
}

impl SSHKeys {
    #[allow(dead_code)]
    pub fn print(&self) {
        println!("private_key {:?}", self.private_key);
        println!("auth_key {:?}", self.auth_key);
    }

    /// Initialize SSH key files for in-tree usage.
    ///
    /// Requires the environment variable FUCHSIA_DIR & FUCHSIA_BUILD_DIR to be specified.
    pub fn from_tree_env() -> Result<SSHKeys> {
        let ssh_file = File::open(read_env_path("FUCHSIA_DIR")?.join(".fx-ssh-path"))?;
        let ssh_file = BufReader::new(ssh_file);
        let mut lines = ssh_file.lines();

        let private_key = PathBuf::from(lines.next().unwrap()?);
        let auth_key = PathBuf::from(lines.next().unwrap()?);

        Ok(SSHKeys { auth_key: auth_key, private_key: private_key })
    }

    /// Initialize SSH key files for GN SDK usage.
    ///
    /// Requires SSH keys to have been generated and stored in $HOME/.ssh/...
    pub fn from_sdk_env() -> Result<SSHKeys> {
        let keys = SSHKeys {
            auth_key: home_dir().unwrap_or_default().join(".ssh/fuchsia_authorized_keys"),
            private_key: home_dir().unwrap_or_default().join(".ssh/fuchsia_ed25519"),
        };
        Ok(keys)
    }

    pub fn stage_files(&mut self, dir: &PathBuf) -> Result<()> {
        let vdl_priv_key_dest = dir.join("id_ed25519");
        let vdl_priv_key_src = self.private_key.as_path();
        unix::fs::symlink(&vdl_priv_key_src, &vdl_priv_key_dest)?;
        self.private_key = vdl_priv_key_dest.to_path_buf();

        let vdl_auth_key_dest = dir.join("id_ed25519.pub");
        let vdl_auth_key_src = self.auth_key.as_path();
        unix::fs::symlink(&vdl_auth_key_src, &vdl_auth_key_dest)?;
        self.auth_key = vdl_auth_key_dest.to_path_buf();

        Ok(())
    }
}

#[derive(Debug)]
pub struct VDLArgs {
    pub headless: bool,
    pub tuntap: bool,
    pub enable_grpcwebproxy: bool,
    pub enable_hidpi_scaling: bool,
    pub grpcwebproxy_port: String,
    pub upscript: String,
    pub packages_to_serve: String,
    pub image_size: String,
    pub device_proto: String,
    pub gpu: String,
    pub pointing_device: String,
    pub gcs_bucket: String,
    pub gcs_build_id: String,
    pub gcs_image_archive: String,
}

impl From<&StartCommand> for VDLArgs {
    fn from(cmd: &StartCommand) -> Self {
        let mut gpu = "swiftshader_indirect";
        if cmd.host_gpu {
            gpu = "host";
        }
        if cmd.software_gpu {
            gpu = "swiftshader_indirect";
        }
        let mut enable_grpcwebproxy = false;
        let mut grpcwebproxy_port = "0".to_string();

        match cmd.grpcwebproxy {
            Some(port) => {
                enable_grpcwebproxy = true;
                grpcwebproxy_port = format!("{}", port);
            }
            _ => (),
        }
        VDLArgs {
            headless: cmd.headless,
            tuntap: cmd.tuntap,
            enable_hidpi_scaling: cmd.hidpi_scaling,
            upscript: cmd.upscript.as_ref().unwrap_or(&String::from("")).to_string(),
            packages_to_serve: cmd
                .packages_to_serve
                .as_ref()
                .unwrap_or(&String::from(""))
                .to_string(),
            image_size: cmd.image_size.as_ref().unwrap_or(&String::from("2G")).to_string(),
            device_proto: cmd.device_proto.as_ref().unwrap_or(&String::from("")).to_string(),
            gpu: gpu.to_string(),
            pointing_device: cmd
                .pointing_device
                .as_ref()
                .unwrap_or(&String::from("touch"))
                .to_string(),
            enable_grpcwebproxy: enable_grpcwebproxy,
            grpcwebproxy_port: grpcwebproxy_port,
            gcs_bucket: cmd.gcs_bucket.as_ref().unwrap_or(&String::from("fuchsia")).to_string(),
            gcs_build_id: cmd.sdk_version.as_ref().unwrap_or(&String::from("")).to_string(),
            gcs_image_archive: cmd
                .image_name
                .as_ref()
                .unwrap_or(&String::from("qemu-x64"))
                .to_string(),
        }
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use serial_test::serial;
    use std::fs::read_dir;
    use std::io::Write;
    use tempfile::TempDir;

    #[test]
    fn test_convert_start_cmd_to_vdl() {
        let start_command = &StartCommand {
            headless: false,
            tuntap: true,
            hidpi_scaling: false,
            upscript: Some("/path/to/upscript".to_string()),
            packages_to_serve: Some("pkg1.far,pkg2.far".to_string()),
            image_size: None,
            device_proto: None,
            aemu_path: None,
            vdl_path: None,
            host_gpu: true,
            software_gpu: false,
            window_width: 1280,
            window_height: 800,
            grpcwebproxy: None,
            grpcwebproxy_path: None,
            pointing_device: Some("mouse".to_string()),
            aemu_version: Some("git_revision:da1cc2ee512714a176f08b8b5fec035994ca305d".to_string()),
            gcs_bucket: None,
            grpcwebproxy_version: None,
            sdk_version: Some("0.20201130.3.1".to_string()),
            image_name: Some("qemu-x64".to_string()),
            vdl_version: None,
            emulator_log: None,
        };
        let vdl_args: VDLArgs = start_command.into();
        assert_eq!(vdl_args.headless, false);
        assert_eq!(vdl_args.tuntap, true);
        assert_eq!(vdl_args.upscript, "/path/to/upscript");
        assert_eq!(vdl_args.packages_to_serve, "pkg1.far,pkg2.far");
        assert_eq!(vdl_args.image_size, "2G");
        assert_eq!(vdl_args.device_proto, "");
        assert_eq!(vdl_args.gpu, "host");
    }

    #[test]
    #[serial]
    fn test_host_tools() -> Result<()> {
        env::set_var("HOST_OUT_DIR", "/host/out");
        env::set_var("PREBUILT_AEMU_DIR", "/host/out/aemu");
        env::set_var("PREBUILT_VDL_DIR", "/host/out/vdl");
        env::set_var("PREBUILT_GRPCWEBPROXY_DIR", "/host/out/grpcwebproxy");

        let host_tools = HostTools::from_tree_env()?;
        assert_eq!(host_tools.aemu.to_str().unwrap(), "/host/out/aemu/emulator");
        assert_eq!(host_tools.vdl.to_str().unwrap(), "/host/out/vdl/device_launcher");
        assert_eq!(host_tools.far.to_str().unwrap(), "/host/out/far");
        assert_eq!(host_tools.fvm.to_str().unwrap(), "/host/out/fvm");
        assert_eq!(host_tools.pm.to_str().unwrap(), "/host/out/pm");
        assert_eq!(host_tools.device_finder.to_str().unwrap(), "/host/out/device-finder");
        assert_eq!(host_tools.zbi.to_str().unwrap(), "/host/out/zbi");
        Ok(())
    }

    #[test]
    #[serial]
    fn test_host_tools_no_env_var() -> Result<()> {
        env::set_var("HOST_OUT_DIR", "/host/out");
        env::remove_var("PREBUILT_AEMU_DIR");
        env::remove_var("PREBUILT_VDL_DIR");
        env::remove_var("PREBUILT_GRPCWEBPROXY_DIR");

        let host_tools = HostTools::from_tree_env()?;
        assert!(host_tools.aemu.as_os_str().is_empty());
        assert!(host_tools.vdl.as_os_str().is_empty());
        assert!(host_tools.grpcwebproxy.as_os_str().is_empty());
        assert_eq!(host_tools.far.to_str().unwrap(), "/host/out/far");
        assert_eq!(host_tools.fvm.to_str().unwrap(), "/host/out/fvm");
        assert_eq!(host_tools.pm.to_str().unwrap(), "/host/out/pm");
        assert_eq!(host_tools.device_finder.to_str().unwrap(), "/host/out/device-finder");
        assert_eq!(host_tools.zbi.to_str().unwrap(), "/host/out/zbi");
        Ok(())
    }

    #[test]
    fn test_image_files() -> Result<()> {
        env::set_var("FUCHSIA_BUILD_DIR", "/build/out");
        env::set_var("IMAGE_ZIRCONA_ZBI", "zircona");
        env::set_var("IMAGE_QEMU_KERNEL_RAW", "kernel");
        env::set_var("IMAGE_FVM_RAW", "fvm");

        let mut image_files = ImageFiles::from_tree_env()?;
        assert_eq!(image_files.zbi.to_str().unwrap(), "/build/out/zircona");
        assert_eq!(image_files.kernel.to_str().unwrap(), "/build/out/kernel");
        assert_eq!(image_files.fvm.to_str().unwrap(), "/build/out/fvm");
        assert_eq!(image_files.build_args.to_str().unwrap(), "/build/out/args.gn");
        assert_eq!(image_files.amber_files.to_str().unwrap(), "/build/out/amber-files");

        let tmp_dir = TempDir::new()?.into_path();
        image_files.stage_files(&tmp_dir)?;
        assert_eq!(image_files.kernel.to_str(), tmp_dir.join("femu_kernel").to_str());

        Ok(())
    }

    #[test]
    fn test_ssh_files() -> Result<()> {
        let data = format!(
            "/usr/local/home/foo/.ssh/fuchsia_ed25519
/usr/local/home/foo/.ssh/fuchsia_authorized_keys
",
        );
        let tmp_dir = TempDir::new()?.into_path();
        File::create(tmp_dir.join(".fx-ssh-path"))?.write_all(data.as_bytes())?;

        env::set_var("FUCHSIA_DIR", tmp_dir.to_str().unwrap());
        env::set_var("FUCHSIA_BUILD_DIR", "/build/out");
        let mut ssh_files = SSHKeys::from_tree_env()?;
        assert_eq!(
            ssh_files.private_key.to_str().unwrap(),
            "/usr/local/home/foo/.ssh/fuchsia_ed25519"
        );
        assert_eq!(
            ssh_files.auth_key.to_str().unwrap(),
            "/usr/local/home/foo/.ssh/fuchsia_authorized_keys"
        );
        ssh_files.stage_files(&tmp_dir)?;
        assert_eq!(ssh_files.private_key.to_str(), tmp_dir.join("id_ed25519").to_str());
        Ok(())
    }

    #[test]
    fn test_sdk_data_dir() -> Result<()> {
        let tmp_dir = TempDir::new()?.into_path();
        env::set_var("FUCHSIA_SDK_DATA_DIR", tmp_dir.to_str().unwrap());
        let p = get_sdk_data_dir()?;
        assert_eq!(p.to_str(), tmp_dir.to_str());
        Ok(())
    }

    #[test]
    fn test_download_and_extract() -> Result<()> {
        let tmp_dir = TempDir::new()?.into_path();
        env::set_var("FEMU_DOWNLOAD_DIR", tmp_dir.to_str().unwrap());
        let host_tools = HostTools::from_sdk_env()?;
        let mut unzipped_root =
            host_tools.download_and_extract("latest".to_string(), "vdl".to_string())?;

        let mut has_extract = false;
        for path in read_dir(&unzipped_root)? {
            let entry = path?;
            let p = entry.path();
            println!("Found path {}", p.display());
            if p.ends_with("device_launcher") {
                has_extract = true;
            }
        }
        assert!(has_extract);

        // Download "latest" again should trigger a cleanup and re-download
        unzipped_root = host_tools.download_and_extract("latest".to_string(), "vdl".to_string())?;
        has_extract = false;
        for path in read_dir(&unzipped_root)? {
            let entry = path?;
            let p = entry.path();
            println!("Found path {}", p.display());
            if p.ends_with("device_launcher") {
                has_extract = true;
            }
        }
        assert!(has_extract);
        Ok(())
    }
}
