// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

//! Common Parquet errors and macros.

use std::{cell, convert, io, result, str};

#[cfg(any(feature = "arrow", test))]
use arrow::error::ArrowError;

#[derive(Debug, PartialEq, Clone)]
pub enum ParquetError {
    /// General Parquet error.
    /// Returned when code violates normal workflow of working with Parquet files.
    General(String),
    /// "Not yet implemented" Parquet error.
    /// Returned when functionality is not yet available.
    NYI(String),
    /// "End of file" Parquet error.
    /// Returned when IO related failures occur, e.g. when there are not enough bytes to
    /// decode.
    EOF(String),
    #[cfg(any(feature = "arrow", test))]
    /// Arrow error.
    /// Returned when reading into arrow or writing from arrow.
    ArrowError(String),
    IndexOutOfBound(usize, usize),
}

impl std::fmt::Display for ParquetError {
    fn fmt(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result {
        match *self {
            ParquetError::General(ref message) => {
                write!(fmt, "Parquet error: {}", message)
            }
            ParquetError::NYI(ref message) => write!(fmt, "NYI: {}", message),
            ParquetError::EOF(ref message) => write!(fmt, "EOF: {}", message),
            #[cfg(any(feature = "arrow", test))]
            ParquetError::ArrowError(ref message) => write!(fmt, "Arrow: {}", message),
            ParquetError::IndexOutOfBound(ref index, ref bound) => {
                write!(fmt, "Index {} out of bound: {}", index, bound)
            }
        }
    }
}

impl std::error::Error for ParquetError {
    fn cause(&self) -> Option<&dyn ::std::error::Error> {
        None
    }
}

impl From<io::Error> for ParquetError {
    fn from(e: io::Error) -> ParquetError {
        ParquetError::General(format!("underlying IO error: {}", e))
    }
}

#[cfg(any(feature = "snap", test))]
impl From<snap::Error> for ParquetError {
    fn from(e: snap::Error) -> ParquetError {
        ParquetError::General(format!("underlying snap error: {}", e))
    }
}

impl From<thrift::Error> for ParquetError {
    fn from(e: thrift::Error) -> ParquetError {
        ParquetError::General(format!("underlying Thrift error: {}", e))
    }
}

impl From<cell::BorrowMutError> for ParquetError {
    fn from(e: cell::BorrowMutError) -> ParquetError {
        ParquetError::General(format!("underlying borrow error: {}", e))
    }
}

impl From<str::Utf8Error> for ParquetError {
    fn from(e: str::Utf8Error) -> ParquetError {
        ParquetError::General(format!("underlying utf8 error: {}", e))
    }
}

#[cfg(any(feature = "arrow", test))]
impl From<ArrowError> for ParquetError {
    fn from(e: ArrowError) -> ParquetError {
        ParquetError::ArrowError(format!("underlying Arrow error: {}", e))
    }
}

/// A specialized `Result` for Parquet errors.
pub type Result<T> = result::Result<T, ParquetError>;

// ----------------------------------------------------------------------
// Conversion from `ParquetError` to other types of `Error`s

impl convert::From<ParquetError> for io::Error {
    fn from(e: ParquetError) -> Self {
        io::Error::new(io::ErrorKind::Other, e)
    }
}

// ----------------------------------------------------------------------
// Convenient macros for different errors

macro_rules! general_err {
    ($fmt:expr) => (ParquetError::General($fmt.to_owned()));
    ($fmt:expr, $($args:expr),*) => (ParquetError::General(format!($fmt, $($args),*)));
    ($e:expr, $fmt:expr) => (ParquetError::General($fmt.to_owned(), $e));
    ($e:ident, $fmt:expr, $($args:tt),*) => (
        ParquetError::General(&format!($fmt, $($args),*), $e));
}

macro_rules! nyi_err {
    ($fmt:expr) => (ParquetError::NYI($fmt.to_owned()));
    ($fmt:expr, $($args:expr),*) => (ParquetError::NYI(format!($fmt, $($args),*)));
}

macro_rules! eof_err {
    ($fmt:expr) => (ParquetError::EOF($fmt.to_owned()));
    ($fmt:expr, $($args:expr),*) => (ParquetError::EOF(format!($fmt, $($args),*)));
}

// ----------------------------------------------------------------------
// Convert parquet error into other errors

#[cfg(any(feature = "arrow", test))]
impl Into<ArrowError> for ParquetError {
    fn into(self) -> ArrowError {
        ArrowError::ParquetError(format!("{}", self))
    }
}
