// Copyright 2016 rustc-version-rs developers
//
// 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.

#![warn(missing_docs)]

//! Simple library for getting the version information of a `rustc`
//! compiler.
//!
//! This can be used by build scripts or other tools dealing with Rust sources
//! to make decisions based on the version of the compiler.
//!
//! It calls `$RUSTC --version -v` and parses the output, falling
//! back to `rustc` if `$RUSTC` is not set.
//!
//! # Example
//!
//! ```rust
//! // This could be a cargo build script
//!
//! use rustc_version::{version, version_meta, Channel, Version};
//!
//! // Assert we haven't travelled back in time
//! assert!(version().unwrap().major >= 1);
//!
//! // Set cfg flags depending on release channel
//! match version_meta().unwrap().channel {
//!     Channel::Stable => {
//!         println!("cargo:rustc-cfg=RUSTC_IS_STABLE");
//!     }
//!     Channel::Beta => {
//!         println!("cargo:rustc-cfg=RUSTC_IS_BETA");
//!     }
//!     Channel::Nightly => {
//!         println!("cargo:rustc-cfg=RUSTC_IS_NIGHTLY");
//!     }
//!     Channel::Dev => {
//!         println!("cargo:rustc-cfg=RUSTC_IS_DEV");
//!     }
//! }
//!
//! // Check for a minimum version
//! if version().unwrap() >= Version::parse("1.4.0").unwrap() {
//!     println!("cargo:rustc-cfg=compiler_has_important_bugfix");
//! }
//! ```

#[cfg(test)]
#[macro_use]
extern crate doc_comment;

#[cfg(test)]
doctest!("../README.md");

use std::collections::HashMap;
use std::process::Command;
use std::{env, error, fmt, io, num, str};
use std::{ffi::OsString, str::FromStr};

// Convenience re-export to allow version comparison without needing to add
// semver crate.
pub use semver::Version;

use Error::*;

/// Release channel of the compiler.
#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)]
pub enum Channel {
    /// Development release channel
    Dev,
    /// Nightly release channel
    Nightly,
    /// Beta release channel
    Beta,
    /// Stable release channel
    Stable,
}

/// LLVM version
///
/// LLVM's version numbering scheme is not semver compatible until version 4.0
///
/// rustc [just prints the major and minor versions], so other parts of the version are not included.
///
/// [just prints the major and minor versions]: https://github.com/rust-lang/rust/blob/b5c9e2448c9ace53ad5c11585803894651b18b0a/compiler/rustc_codegen_llvm/src/llvm_util.rs#L173-L178
#[derive(Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub struct LlvmVersion {
    // fields must be ordered major, minor for comparison to be correct
    /// Major version
    pub major: u64,
    /// Minor version
    pub minor: u64,
    // TODO: expose micro version here
}

impl fmt::Display for LlvmVersion {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "{}.{}", self.major, self.minor)
    }
}

impl FromStr for LlvmVersion {
    type Err = LlvmVersionParseError;

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        let mut parts = s
            .split('.')
            .map(|part| -> Result<u64, LlvmVersionParseError> {
                if part == "0" {
                    Ok(0)
                } else if part.starts_with('0') {
                    Err(LlvmVersionParseError::ComponentMustNotHaveLeadingZeros)
                } else if part.starts_with('-') || part.starts_with('+') {
                    Err(LlvmVersionParseError::ComponentMustNotHaveSign)
                } else {
                    Ok(part.parse()?)
                }
            });

        let major = parts.next().unwrap()?;
        let mut minor = 0;

        if let Some(part) = parts.next() {
            minor = part?;
        } else if major < 4 {
            // LLVM versions earlier than 4.0 have significant minor versions, so require the minor version in this case.
            return Err(LlvmVersionParseError::MinorVersionRequiredBefore4);
        }

        if let Some(Err(e)) = parts.next() {
            return Err(e);
        }

        if parts.next().is_some() {
            return Err(LlvmVersionParseError::TooManyComponents);
        }

        Ok(Self { major, minor })
    }
}

/// Rustc version plus metadata like git short hash and build date.
#[derive(Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub struct VersionMeta {
    /// Version of the compiler
    pub semver: Version,

    /// Git short hash of the build of the compiler
    pub commit_hash: Option<String>,

    /// Commit date of the compiler
    pub commit_date: Option<String>,

    /// Build date of the compiler; this was removed between Rust 1.0.0 and 1.1.0.
    pub build_date: Option<String>,

    /// Release channel of the compiler
    pub channel: Channel,

    /// Host target triple of the compiler
    pub host: String,

    /// Short version string of the compiler
    pub short_version_string: String,

    /// Version of LLVM used by the compiler
    pub llvm_version: Option<LlvmVersion>,
}

impl VersionMeta {
    /// Returns the version metadata for `cmd`, which should be a `rustc` command.
    pub fn for_command(mut cmd: Command) -> Result<VersionMeta> {
        let out = cmd
            .arg("-vV")
            .output()
            .map_err(Error::CouldNotExecuteCommand)?;

        if !out.status.success() {
            return Err(Error::CommandError {
                stdout: String::from_utf8_lossy(&out.stdout).into(),
                stderr: String::from_utf8_lossy(&out.stderr).into(),
            });
        }

        version_meta_for(str::from_utf8(&out.stdout)?)
    }
}

/// Returns the `rustc` SemVer version.
pub fn version() -> Result<Version> {
    Ok(version_meta()?.semver)
}

/// Returns the `rustc` SemVer version and additional metadata
/// like the git short hash and build date.
pub fn version_meta() -> Result<VersionMeta> {
    let cmd = env::var_os("RUSTC").unwrap_or_else(|| OsString::from("rustc"));

    VersionMeta::for_command(Command::new(cmd))
}

/// Parses a "rustc -vV" output string and returns
/// the SemVer version and additional metadata
/// like the git short hash and build date.
pub fn version_meta_for(verbose_version_string: &str) -> Result<VersionMeta> {
    let mut map = HashMap::new();
    for (i, line) in verbose_version_string.lines().enumerate() {
        if i == 0 {
            map.insert("short", line);
            continue;
        }

        let mut parts = line.splitn(2, ": ");
        let key = match parts.next() {
            Some(key) => key,
            None => continue,
        };

        if let Some(value) = parts.next() {
            map.insert(key, value);
        }
    }

    let short_version_string = expect_key("short", &map)?;
    let host = expect_key("host", &map)?;
    let release = expect_key("release", &map)?;
    let semver: Version = release.parse()?;

    let channel = match semver.pre.split('.').next().unwrap() {
        "" => Channel::Stable,
        "dev" => Channel::Dev,
        "beta" => Channel::Beta,
        "nightly" => Channel::Nightly,
        x => return Err(Error::UnknownPreReleaseTag(x.to_owned())),
    };

    let commit_hash = expect_key_or_unknown("commit-hash", &map)?;
    let commit_date = expect_key_or_unknown("commit-date", &map)?;
    let build_date = map
        .get("build-date")
        .filter(|&v| *v != "unknown")
        .map(|&v| String::from(v));
    let llvm_version = match map.get("LLVM version") {
        Some(&v) => Some(v.parse()?),
        None => None,
    };

    Ok(VersionMeta {
        semver,
        commit_hash,
        commit_date,
        build_date,
        channel,
        host,
        short_version_string,
        llvm_version,
    })
}

fn expect_key_or_unknown(key: &str, map: &HashMap<&str, &str>) -> Result<Option<String>, Error> {
    match map.get(key) {
        Some(&v) if v == "unknown" => Ok(None),
        Some(&v) => Ok(Some(String::from(v))),
        None => Err(Error::UnexpectedVersionFormat),
    }
}

fn expect_key(key: &str, map: &HashMap<&str, &str>) -> Result<String, Error> {
    map.get(key)
        .map(|&v| String::from(v))
        .ok_or(Error::UnexpectedVersionFormat)
}

/// LLVM Version Parse Error
#[derive(Debug)]
pub enum LlvmVersionParseError {
    /// An error occurred in parsing a version component as an integer
    ParseIntError(num::ParseIntError),
    /// A version component must not have leading zeros
    ComponentMustNotHaveLeadingZeros,
    /// A version component has a sign
    ComponentMustNotHaveSign,
    /// Minor version component must be zero on LLVM versions later than 4.0
    MinorVersionMustBeZeroAfter4,
    /// Minor version component is required on LLVM versions earlier than 4.0
    MinorVersionRequiredBefore4,
    /// Too many components
    TooManyComponents,
}

impl From<num::ParseIntError> for LlvmVersionParseError {
    fn from(e: num::ParseIntError) -> Self {
        LlvmVersionParseError::ParseIntError(e)
    }
}

impl fmt::Display for LlvmVersionParseError {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self {
            LlvmVersionParseError::ParseIntError(e) => {
                write!(f, "error parsing LLVM version component: {}", e)
            }
            LlvmVersionParseError::ComponentMustNotHaveLeadingZeros => {
                write!(f, "a version component must not have leading zeros")
            }
            LlvmVersionParseError::ComponentMustNotHaveSign => {
                write!(f, "a version component must not have a sign")
            }
            LlvmVersionParseError::MinorVersionMustBeZeroAfter4 => write!(
                f,
                "LLVM's minor version component must be 0 for versions greater than 4.0"
            ),
            LlvmVersionParseError::MinorVersionRequiredBefore4 => write!(
                f,
                "LLVM's minor version component is required for versions less than 4.0"
            ),
            LlvmVersionParseError::TooManyComponents => write!(f, "too many version components"),
        }
    }
}

impl error::Error for LlvmVersionParseError {
    fn source(&self) -> Option<&(dyn error::Error + 'static)> {
        match self {
            LlvmVersionParseError::ParseIntError(e) => Some(e),
            LlvmVersionParseError::ComponentMustNotHaveLeadingZeros
            | LlvmVersionParseError::ComponentMustNotHaveSign
            | LlvmVersionParseError::MinorVersionMustBeZeroAfter4
            | LlvmVersionParseError::MinorVersionRequiredBefore4
            | LlvmVersionParseError::TooManyComponents => None,
        }
    }
}

/// The error type for this crate.
#[derive(Debug)]
pub enum Error {
    /// An error occurred while trying to find the `rustc` to run.
    CouldNotExecuteCommand(io::Error),
    /// Error output from the command that was run.
    CommandError {
        /// stdout output from the command
        stdout: String,
        /// stderr output from the command
        stderr: String,
    },
    /// The output of `rustc -vV` was not valid utf-8.
    Utf8Error(str::Utf8Error),
    /// The output of `rustc -vV` was not in the expected format.
    UnexpectedVersionFormat,
    /// An error occurred in parsing the semver.
    SemVerError(semver::Error),
    /// The pre-release tag is unknown.
    UnknownPreReleaseTag(String),
    /// An error occurred in parsing a `LlvmVersion`.
    LlvmVersionError(LlvmVersionParseError),
}

impl fmt::Display for Error {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match *self {
            CouldNotExecuteCommand(ref e) => write!(f, "could not execute command: {}", e),
            CommandError {
                ref stdout,
                ref stderr,
            } => write!(
                f,
                "error from command -- stderr:\n\n{}\n\nstderr:\n\n{}",
                stderr, stdout,
            ),
            Utf8Error(_) => write!(f, "invalid UTF-8 output from `rustc -vV`"),
            UnexpectedVersionFormat => write!(f, "unexpected `rustc -vV` format"),
            SemVerError(ref e) => write!(f, "error parsing version: {}", e),
            UnknownPreReleaseTag(ref i) => write!(f, "unknown pre-release tag: {}", i),
            LlvmVersionError(ref e) => write!(f, "error parsing LLVM's version: {}", e),
        }
    }
}

impl error::Error for Error {
    fn source(&self) -> Option<&(dyn error::Error + 'static)> {
        match *self {
            CouldNotExecuteCommand(ref e) => Some(e),
            CommandError { .. } => None,
            Utf8Error(ref e) => Some(e),
            UnexpectedVersionFormat => None,
            SemVerError(ref e) => Some(e),
            UnknownPreReleaseTag(_) => None,
            LlvmVersionError(ref e) => Some(e),
        }
    }
}

macro_rules! impl_from {
    ($($err_ty:ty => $variant:ident),* $(,)*) => {
        $(
            impl From<$err_ty> for Error {
                fn from(e: $err_ty) -> Error {
                    Error::$variant(e)
                }
            }
        )*
    }
}

impl_from! {
    str::Utf8Error => Utf8Error,
    semver::Error => SemVerError,
    LlvmVersionParseError => LlvmVersionError,
}

/// The result type for this crate.
pub type Result<T, E = Error> = std::result::Result<T, E>;
