// Copyright 2019 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 {
    anyhow::format_err, fidl_fuchsia_bluetooth as bt, fidl_fuchsia_bluetooth_sys as sys,
    fuchsia_bluetooth::bt_fidl_status,
};

/// Type representing Possible errors raised in the operation of BT-GAP
#[derive(Debug)]
pub enum Error {
    /// Internal bt-gap Error
    InternalError(anyhow::Error),

    /// Host Error
    HostError(bt::Error),

    /// fuchsia.bluetooth.sys API errors. Used to encapsulate errors that are reported by bt-host
    /// and for the fuchsia.bluetooth.sys.Access API.
    SysError(sys::Error),
}

pub type Result<T> = std::result::Result<T, Error>;

impl Error {
    pub fn as_status(self) -> bt::Status {
        match self {
            Error::HostError(err) => bt::Status { error: Some(Box::new(err)) },
            Error::InternalError(err) => bt_fidl_status!(Failed, format!("{}", err)),
            Error::SysError(err) => {
                bt::Status { error: Some(Box::new(sys_error_to_deprecated(err))) }
            }
        }
    }

    pub fn no_host() -> Error {
        Error::HostError(bt::Error {
            error_code: bt::ErrorCode::BluetoothNotAvailable,
            protocol_error_code: 0,
            description: Some("No Host found".to_string()),
        })
    }

    pub fn as_failure(self) -> anyhow::Error {
        match self {
            Error::InternalError(err) => err,
            Error::HostError(err) => format_err!(
                "Host Error: {}",
                err.description.unwrap_or("Unknown Host Error".to_string())
            ),
            Error::SysError(err) => format_err!("Host Error: {:?}", err),
        }
    }
}

impl Into<anyhow::Error> for Error {
    fn into(self) -> anyhow::Error {
        self.as_failure()
    }
}

impl From<bt::Error> for Error {
    fn from(err: bt::Error) -> Error {
        Error::HostError(err)
    }
}

impl From<sys::Error> for Error {
    fn from(err: sys::Error) -> Error {
        Error::SysError(err)
    }
}

impl From<anyhow::Error> for Error {
    fn from(err: anyhow::Error) -> Error {
        Error::InternalError(err)
    }
}

impl From<fidl::Error> for Error {
    fn from(err: fidl::Error) -> Error {
        Error::InternalError(format_err!(format!("Internal FIDL error: {}", err)))
    }
}

pub fn from_fidl_status(r: fidl::Result<bt::Status>) -> Result<()> {
    match r {
        Ok(status) => status.as_result(),
        Err(e) => Err(Error::from(e)),
    }
}

pub fn from_fidl_result<T>(r: fidl::Result<std::result::Result<T, sys::Error>>) -> Result<T> {
    match r {
        Ok(r) => r.map_err(Error::from),
        Err(e) => Err(Error::from(e)),
    }
}

// Maps a fuchsia.bluetooth.sys.Error value to a fuchsia.bluetooth.Error. This is maintained for
// compatibility until fuchsia.bluetooth.control and fuchsia.bluetooth.Status are removed.
fn sys_error_to_deprecated(e: sys::Error) -> bt::Error {
    bt::Error {
        error_code: match e {
            sys::Error::Failed => bt::ErrorCode::Failed,
            sys::Error::PeerNotFound => bt::ErrorCode::NotFound,
            sys::Error::TimedOut => bt::ErrorCode::TimedOut,
            sys::Error::Canceled => bt::ErrorCode::Canceled,
            sys::Error::InProgress => bt::ErrorCode::InProgress,
            sys::Error::NotSupported => bt::ErrorCode::NotSupported,
            sys::Error::InvalidArguments => bt::ErrorCode::InvalidArguments,
        },
        protocol_error_code: 0,
        description: None,
    }
}

pub trait StatusExt {
    fn as_result(self) -> Result<()>;
}

impl StatusExt for bt::Status {
    fn as_result(self) -> Result<()> {
        match self.error {
            Some(err) => Err((*err).into()),
            None => Ok(()),
        }
    }
}

pub fn status_response(result: Result<()>) -> bt::Status {
    match result {
        Ok(()) => bt_fidl_status!(),
        Err(err) => err.as_status(),
    }
}
