// Copyright 2021-2022 Ian Jackson and contributors to Hippotat
// SPDX-License-Identifier: GPL-3.0-or-later WITH LicenseRef-Hippotat-OpenSSL-Exception
// There is NO WARRANTY.

pub use std::array;
pub use std::collections::{BTreeSet, HashMap, VecDeque};
pub use std::convert::{Infallible, TryFrom, TryInto};
pub use std::borrow::Cow;
pub use std::cell::{RefCell, RefMut};
pub use std::cmp::{min, max};
pub use std::env;
pub use std::fs;
pub use std::fmt::{self, Debug, Display, Write as _};
pub use std::future::Future;
pub use std::io::{self, Cursor, ErrorKind, IoSlice, Read as _, Write as _};
pub use std::iter;
pub use std::mem;
pub use std::net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr};
pub use std::num::TryFromIntError;
pub use std::os::fd::{BorrowedFd, OwnedFd};
pub use std::os::raw::c_int;
pub use std::path::{Path, PathBuf};
pub use std::panic::{self, AssertUnwindSafe};
pub use std::process;
pub use std::pin::Pin;
pub use std::str::{self, FromStr};
pub use std::sync::Arc;
pub use std::task::Poll;
pub use std::time::{SystemTime, UNIX_EPOCH};

pub use derive_deftly::{define_derive_deftly, Deftly};
pub use educe::Educe;
pub use either::Either;
pub use easy_ext::ext;
pub use fehler::{throw, throws};
pub use futures::{poll, future, FutureExt, StreamExt, TryStreamExt};
pub use hyper::body::{Bytes, Buf};
pub use hyper::{Method};
pub use ipnet::IpNet;
pub use itertools::{chain, iproduct, izip, Itertools};
pub use lazy_regex::{regex_captures, regex_is_match, regex_replace_all};
pub use lazy_static::lazy_static;
pub use log::{trace, debug, info, warn, error};
pub use memchr::memmem;
pub use pin_project_lite::pin_project;
pub use reqwest::Url;
pub use subtle::ConstantTimeEq;
pub use thiserror::Error;
pub use tokio::io::{AsyncBufReadExt, AsyncWriteExt};
pub use tokio::pin;
pub use tokio::select;
pub use tokio::sync::{mpsc, oneshot};
pub use tokio::task::{self, JoinError, JoinHandle};
pub use tokio::time::{Duration, Instant};
pub use void::{self, Void, ResultVoidExt, ResultVoidErrExt};

pub use eyre as anyhow;
pub use eyre::eyre as anyhow;
pub use eyre::WrapErr;
pub use eyre::Error as AE;

pub use crate::compat;
pub use crate::config::{self, InstanceConfig, PrintConfigOpt};
pub use crate::config::{InspectableConfig, InspectableConfigValue};
pub use crate::config::{DisplayInspectable, U32Ext as _};
pub use crate::impl_inspectable_config_value;
pub use crate::ini;
pub use crate::ipif::Ipif;
pub use crate::multipart::{self, PartName, MetadataFieldIterator};
pub use crate::utils::*;
pub use crate::queue::*;
pub use crate::reporter::*;
pub use crate::types::*;
pub use crate::slip::{self, *};

pub type ReqNum = u64;

pub use ErrorKind as EK;
pub use PacketError as PE;
pub use tokio::io as t_io;
pub use tokio::process as t_proc;

pub const SLIP_END:     u8 = 0o300; // c0
pub const SLIP_ESC:     u8 = 0o333; // db
pub const SLIP_ESC_END: u8 = 0o334; // dc
pub const SLIP_ESC_ESC: u8 = 0o335; // dd
pub const SLIP_MIME_ESC: u8 = b'-'; // 2d

pub const MAX_OVERHEAD: usize = 2_000;

mod base64_config {
  use base64::engine::*;
  // Emit padding when we base64 encode things, but tolerate its lack
  // hippotat 1.x always ignored padding (except for 1.1.8).
  // Eventually we plan to stop emitting padding.
  pub const BASE64_CONFIG: GeneralPurpose = GeneralPurpose::new(
    &base64::alphabet::STANDARD,
    GeneralPurposeConfig::new()
      .with_encode_padding(true)
      .with_decode_padding_mode(DecodePaddingMode::Indifferent)
  );
}
pub use base64_config::*;
pub use base64::Engine as _;

pub fn default<T:Default>() -> T { Default::default() }
