use std::borrow::Cow;
use std::cmp::min;
use std::ops::{Add, Sub};

use rustc_span::Span;

use crate::Config;
use crate::rewrite::ExceedsMaxWidthError;

#[derive(Copy, Clone, Debug)]
pub(crate) struct Indent {
    // Width of the block indent, in characters. Must be a multiple of
    // Config::tab_spaces.
    pub(crate) block_indent: usize,
    // Alignment in characters.
    pub(crate) alignment: usize,
}

// INDENT_BUFFER.len() = 81
const INDENT_BUFFER_LEN: usize = 80;
const INDENT_BUFFER: &str =
    "\n                                                                                ";

impl Indent {
    pub(crate) fn new(block_indent: usize, alignment: usize) -> Indent {
        Indent {
            block_indent,
            alignment,
        }
    }

    pub(crate) fn from_width(config: &Config, width: usize) -> Indent {
        if config.hard_tabs() {
            let tab_num = width / config.tab_spaces();
            let alignment = width % config.tab_spaces();
            Indent::new(config.tab_spaces() * tab_num, alignment)
        } else {
            Indent::new(width, 0)
        }
    }

    pub(crate) fn empty() -> Indent {
        Indent::new(0, 0)
    }

    pub(crate) fn block_only(&self) -> Indent {
        Indent {
            block_indent: self.block_indent,
            alignment: 0,
        }
    }

    pub(crate) fn block_indent(mut self, config: &Config) -> Indent {
        self.block_indent += config.tab_spaces();
        self
    }

    pub(crate) fn block_unindent(mut self, config: &Config) -> Indent {
        if self.block_indent < config.tab_spaces() {
            Indent::new(self.block_indent, 0)
        } else {
            self.block_indent -= config.tab_spaces();
            self
        }
    }

    pub(crate) fn width(&self) -> usize {
        self.block_indent + self.alignment
    }

    pub(crate) fn to_string(&self, config: &Config) -> Cow<'static, str> {
        self.to_string_inner(config, 1)
    }

    pub(crate) fn to_string_with_newline(&self, config: &Config) -> Cow<'static, str> {
        self.to_string_inner(config, 0)
    }

    fn to_string_inner(&self, config: &Config, offset: usize) -> Cow<'static, str> {
        let (num_tabs, num_spaces) = if config.hard_tabs() {
            (self.block_indent / config.tab_spaces(), self.alignment)
        } else {
            (0, self.width())
        };
        let num_chars = num_tabs + num_spaces;
        if num_tabs == 0 && num_chars + offset <= INDENT_BUFFER_LEN {
            Cow::from(&INDENT_BUFFER[offset..=num_chars])
        } else {
            let mut indent = String::with_capacity(num_chars + if offset == 0 { 1 } else { 0 });
            if offset == 0 {
                indent.push('\n');
            }
            for _ in 0..num_tabs {
                indent.push('\t')
            }
            for _ in 0..num_spaces {
                indent.push(' ')
            }
            Cow::from(indent)
        }
    }
}

impl Add for Indent {
    type Output = Indent;

    fn add(self, rhs: Indent) -> Indent {
        Indent {
            block_indent: self.block_indent + rhs.block_indent,
            alignment: self.alignment + rhs.alignment,
        }
    }
}

impl Sub for Indent {
    type Output = Indent;

    fn sub(self, rhs: Indent) -> Indent {
        Indent::new(
            self.block_indent - rhs.block_indent,
            self.alignment - rhs.alignment,
        )
    }
}

impl Add<usize> for Indent {
    type Output = Indent;

    fn add(self, rhs: usize) -> Indent {
        Indent::new(self.block_indent, self.alignment + rhs)
    }
}

impl Sub<usize> for Indent {
    type Output = Indent;

    fn sub(self, rhs: usize) -> Indent {
        Indent::new(self.block_indent, self.alignment - rhs)
    }
}

// 8096 is close enough to infinite for rustfmt.
const INFINITE_SHAPE_WIDTH: usize = 8096;

#[derive(Copy, Clone, Debug)]
pub(crate) struct Shape {
    pub(crate) width: usize,
    // The current indentation of code.
    pub(crate) indent: Indent,
    // Indentation + any already emitted text on the first line of the current
    // statement.
    pub(crate) offset: usize,
}

impl Shape {
    /// `indent` is the indentation of the first line. The next lines
    /// should begin with at least `indent` spaces (except backwards
    /// indentation). The first line should not begin with indentation.
    /// `width` is the maximum number of characters on the last line
    /// (excluding `indent`). The width of other lines is not limited by
    /// `width`.
    /// Note that in reality, we sometimes use width for lines other than the
    /// last (i.e., we are conservative).
    // .......*-------*
    //        |       |
    //        |     *-*
    //        *-----|
    // |<------------>|  max width
    // |<---->|          indent
    //        |<--->|    width
    pub(crate) fn legacy(width: usize, indent: Indent) -> Shape {
        Shape {
            width,
            indent,
            offset: indent.alignment,
        }
    }

    pub(crate) fn indented(indent: Indent, config: &Config) -> Shape {
        Shape {
            width: config.max_width().saturating_sub(indent.width()),
            indent,
            offset: indent.alignment,
        }
    }

    pub(crate) fn with_max_width(&self, config: &Config) -> Shape {
        Shape {
            width: config.max_width().saturating_sub(self.indent.width()),
            ..*self
        }
    }

    pub(crate) fn visual_indent(&self, delta: usize) -> Shape {
        let alignment = self.offset + delta;
        Shape {
            width: self.width,
            indent: Indent::new(self.indent.block_indent, alignment),
            offset: alignment,
        }
    }

    pub(crate) fn block_indent(&self, delta: usize) -> Shape {
        if self.indent.alignment == 0 {
            Shape {
                width: self.width,
                indent: Indent::new(self.indent.block_indent + delta, 0),
                offset: 0,
            }
        } else {
            Shape {
                width: self.width,
                indent: self.indent + delta,
                offset: self.indent.alignment + delta,
            }
        }
    }

    pub(crate) fn block_left(
        &self,
        delta: usize,
        span: Span,
    ) -> Result<Shape, ExceedsMaxWidthError> {
        self.block_indent(delta).sub_width(delta, span)
    }

    pub(crate) fn add_offset(&self, delta: usize) -> Shape {
        Shape {
            offset: self.offset + delta,
            ..*self
        }
    }

    pub(crate) fn block(&self) -> Shape {
        Shape {
            indent: self.indent.block_only(),
            ..*self
        }
    }

    pub(crate) fn saturating_sub_width(&self, delta: usize) -> Shape {
        Shape {
            width: self.width.saturating_sub(delta),
            ..*self
        }
    }

    pub(crate) fn sub_width(
        &self,
        delta: usize,
        span: Span,
    ) -> Result<Shape, ExceedsMaxWidthError> {
        self.sub_width_opt(delta)
            .ok_or_else(|| self.exceeds_max_width_error(span))
    }

    pub(crate) fn sub_width_opt(&self, delta: usize) -> Option<Shape> {
        self.width
            .checked_sub(delta)
            .map(|width| Shape { width, ..*self })
    }

    pub(crate) fn shrink_left(
        &self,
        delta: usize,
        span: Span,
    ) -> Result<Shape, ExceedsMaxWidthError> {
        self.shrink_left_opt(delta)
            .ok_or_else(|| self.exceeds_max_width_error(span))
    }

    pub(crate) fn shrink_left_opt(&self, delta: usize) -> Option<Shape> {
        self.width.checked_sub(delta).map(|width| Shape {
            width,
            indent: self.indent + delta,
            offset: self.offset + delta,
        })
    }

    pub(crate) fn offset_left(
        &self,
        delta: usize,
        span: Span,
    ) -> Result<Shape, ExceedsMaxWidthError> {
        self.offset_left_opt(delta)
            .ok_or_else(|| self.exceeds_max_width_error(span))
    }

    pub(crate) fn offset_left_opt(&self, delta: usize) -> Option<Shape> {
        self.add_offset(delta).sub_width_opt(delta)
    }

    pub(crate) fn used_width(&self) -> usize {
        self.indent.block_indent + self.offset
    }

    pub(crate) fn rhs_overhead(&self, config: &Config) -> usize {
        config
            .max_width()
            .saturating_sub(self.used_width() + self.width)
    }

    pub(crate) fn comment(&self, config: &Config) -> Shape {
        let width = min(
            self.width,
            config.comment_width().saturating_sub(self.indent.width()),
        );
        Shape { width, ..*self }
    }

    pub(crate) fn to_string_with_newline(&self, config: &Config) -> Cow<'static, str> {
        let mut offset_indent = self.indent;
        offset_indent.alignment = self.offset;
        offset_indent.to_string_inner(config, 0)
    }

    /// Creates a `Shape` with a virtually infinite width.
    pub(crate) fn infinite_width(&self) -> Shape {
        Shape {
            width: INFINITE_SHAPE_WIDTH,
            ..*self
        }
    }

    fn exceeds_max_width_error(&self, span: Span) -> ExceedsMaxWidthError {
        ExceedsMaxWidthError {
            configured_width: self.width,
            span,
        }
    }
}

#[cfg(test)]
mod test {
    use super::*;

    #[test]
    fn indent_add_sub() {
        let indent = Indent::new(4, 8) + Indent::new(8, 12);
        assert_eq!(12, indent.block_indent);
        assert_eq!(20, indent.alignment);

        let indent = indent - Indent::new(4, 4);
        assert_eq!(8, indent.block_indent);
        assert_eq!(16, indent.alignment);
    }

    #[test]
    fn indent_add_sub_alignment() {
        let indent = Indent::new(4, 8) + 4;
        assert_eq!(4, indent.block_indent);
        assert_eq!(12, indent.alignment);

        let indent = indent - 4;
        assert_eq!(4, indent.block_indent);
        assert_eq!(8, indent.alignment);
    }

    #[test]
    fn indent_to_string_spaces() {
        let config = Config::default();
        let indent = Indent::new(4, 8);

        // 12 spaces
        assert_eq!("            ", indent.to_string(&config));
    }

    #[test]
    fn indent_to_string_hard_tabs() {
        let mut config = Config::default();
        config.set().hard_tabs(true);
        let indent = Indent::new(8, 4);

        // 2 tabs + 4 spaces
        assert_eq!("\t\t    ", indent.to_string(&config));
    }

    #[test]
    fn shape_visual_indent() {
        let config = Config::default();
        let indent = Indent::new(4, 8);
        let shape = Shape::legacy(config.max_width(), indent);
        let shape = shape.visual_indent(20);

        assert_eq!(config.max_width(), shape.width);
        assert_eq!(4, shape.indent.block_indent);
        assert_eq!(28, shape.indent.alignment);
        assert_eq!(28, shape.offset);
    }

    #[test]
    fn shape_block_indent_without_alignment() {
        let config = Config::default();
        let indent = Indent::new(4, 0);
        let shape = Shape::legacy(config.max_width(), indent);
        let shape = shape.block_indent(20);

        assert_eq!(config.max_width(), shape.width);
        assert_eq!(24, shape.indent.block_indent);
        assert_eq!(0, shape.indent.alignment);
        assert_eq!(0, shape.offset);
    }

    #[test]
    fn shape_block_indent_with_alignment() {
        let config = Config::default();
        let indent = Indent::new(4, 8);
        let shape = Shape::legacy(config.max_width(), indent);
        let shape = shape.block_indent(20);

        assert_eq!(config.max_width(), shape.width);
        assert_eq!(4, shape.indent.block_indent);
        assert_eq!(28, shape.indent.alignment);
        assert_eq!(28, shape.offset);
    }
}
