use std::fmt::{Display, Write};

use crate::content::Content;

/// The maximum number of characters to print in a single line
/// when [`to_string_pretty`] is used.
const COMPACT_MAX_CHARS: usize = 120;

pub fn format_float<T: Display>(value: T) -> String {
    let mut rv = format!("{}", value);
    if !rv.contains('.') {
        rv.push_str(".0");
    }
    rv
}

#[derive(PartialEq, Eq, Copy, Clone, Debug)]
pub enum Format {
    Condensed,
    SingleLine,
    Pretty,
}

/// Serializes a serializable to JSON.
pub struct Serializer {
    out: String,
    format: Format,
    indentation: usize,
}

impl Serializer {
    /// Creates a new serializer that writes into the given writer.
    pub fn new() -> Serializer {
        Serializer {
            out: String::new(),
            format: Format::Condensed,
            indentation: 0,
        }
    }

    pub fn into_result(self) -> String {
        self.out
    }

    fn write_indentation(&mut self) {
        if self.format == Format::Pretty {
            write!(self.out, "{: ^1$}", "", self.indentation * 2).unwrap();
        }
    }

    fn start_container(&mut self, c: char) {
        self.write_char(c);
        self.indentation += 1;
    }

    fn end_container(&mut self, c: char, empty: bool) {
        self.indentation -= 1;
        if self.format == Format::Pretty && !empty {
            self.write_char('\n');
            self.write_indentation();
        }
        self.write_char(c);
    }

    fn write_comma(&mut self, first: bool) {
        match self.format {
            Format::Pretty => {
                if first {
                    self.write_char('\n');
                } else {
                    self.write_str(",\n");
                }
                self.write_indentation();
            }
            Format::Condensed => {
                if !first {
                    self.write_char(',');
                }
            }
            Format::SingleLine => {
                if !first {
                    self.write_str(", ");
                }
            }
        }
    }

    fn write_colon(&mut self) {
        match self.format {
            Format::Pretty | Format::SingleLine => self.write_str(": "),
            Format::Condensed => self.write_char(':'),
        }
    }

    fn serialize_array(&mut self, items: &[Content]) {
        self.start_container('[');
        for (idx, item) in items.iter().enumerate() {
            self.write_comma(idx == 0);
            self.serialize(item);
        }
        self.end_container(']', items.is_empty());
    }

    fn serialize_object(&mut self, fields: &[(&str, Content)]) {
        self.start_container('{');
        for (idx, (key, value)) in fields.iter().enumerate() {
            self.write_comma(idx == 0);
            self.write_escaped_str(key);
            self.write_colon();
            self.serialize(value);
        }
        self.end_container('}', fields.is_empty());
    }

    pub fn serialize(&mut self, value: &Content) {
        match value {
            Content::Bool(true) => self.write_str("true"),
            Content::Bool(false) => self.write_str("false"),
            Content::U8(n) => write!(self.out, "{}", n).unwrap(),
            Content::U16(n) => write!(self.out, "{}", n).unwrap(),
            Content::U32(n) => write!(self.out, "{}", n).unwrap(),
            Content::U64(n) => write!(self.out, "{}", n).unwrap(),
            Content::U128(n) => write!(self.out, "{}", n).unwrap(),
            Content::I8(n) => write!(self.out, "{}", n).unwrap(),
            Content::I16(n) => write!(self.out, "{}", n).unwrap(),
            Content::I32(n) => write!(self.out, "{}", n).unwrap(),
            Content::I64(n) => write!(self.out, "{}", n).unwrap(),
            Content::I128(n) => write!(self.out, "{}", n).unwrap(),
            Content::F32(f) => {
                if f.is_finite() {
                    self.write_str(&format_float(f));
                } else {
                    self.write_str("null")
                }
            }
            Content::F64(f) => {
                if f.is_finite() {
                    self.write_str(&format_float(f));
                } else {
                    self.write_str("null")
                }
            }
            Content::Char(c) => self.write_escaped_str(&(*c).to_string()),
            Content::String(s) => self.write_escaped_str(s),
            Content::Bytes(bytes) => {
                self.start_container('[');
                for (idx, byte) in bytes.iter().enumerate() {
                    self.write_comma(idx == 0);
                    self.write_str(&byte.to_string());
                }
                self.end_container(']', bytes.is_empty());
            }
            Content::None | Content::Unit | Content::UnitStruct(_) => self.write_str("null"),
            Content::Some(content) => self.serialize(content),
            Content::UnitVariant(_, _, variant) => self.write_escaped_str(variant),
            Content::NewtypeStruct(_, content) => self.serialize(content),
            Content::NewtypeVariant(_, _, variant, content) => {
                self.start_container('{');
                self.write_comma(true);
                self.write_escaped_str(variant);
                self.write_colon();
                self.serialize(content);
                self.end_container('}', false);
            }
            Content::Seq(seq) | Content::Tuple(seq) | Content::TupleStruct(_, seq) => {
                self.serialize_array(seq);
            }
            Content::TupleVariant(_, _, variant, seq) => {
                self.start_container('{');
                self.write_comma(true);
                self.write_escaped_str(variant);
                self.write_colon();
                self.serialize_array(seq);
                self.end_container('}', false);
            }
            Content::Map(map) => {
                self.start_container('{');
                for (idx, (key, value)) in map.iter().enumerate() {
                    self.write_comma(idx == 0);
                    let real_key = key.resolve_inner();
                    if let Content::String(ref s) = real_key {
                        self.write_escaped_str(s);
                    } else if let Some(num) = real_key.as_i64() {
                        self.write_escaped_str(&num.to_string());
                    } else if let Some(num) = real_key.as_i128() {
                        self.write_escaped_str(&num.to_string());
                    } else {
                        panic!("cannot serialize maps without string keys to JSON");
                    }
                    self.write_colon();
                    self.serialize(value);
                }
                self.end_container('}', map.is_empty());
            }
            Content::Struct(_, fields) => {
                self.serialize_object(fields);
            }
            Content::StructVariant(_, _, variant, fields) => {
                self.start_container('{');
                self.write_comma(true);
                self.write_escaped_str(variant);
                self.write_colon();
                self.serialize_object(fields);
                self.end_container('}', false);
            }
        }
    }

    fn write_str(&mut self, s: &str) {
        self.out.push_str(s);
    }

    fn write_char(&mut self, c: char) {
        self.out.push(c);
    }

    fn write_escaped_str(&mut self, value: &str) {
        self.write_char('"');

        let bytes = value.as_bytes();
        let mut start = 0;

        for (i, &byte) in bytes.iter().enumerate() {
            let escape = ESCAPE[byte as usize];
            if escape == 0 {
                continue;
            }

            if start < i {
                self.write_str(&value[start..i]);
            }

            match escape {
                self::BB => self.write_str("\\b"),
                self::TT => self.write_str("\\t"),
                self::NN => self.write_str("\\n"),
                self::FF => self.write_str("\\f"),
                self::RR => self.write_str("\\r"),
                self::QU => self.write_str("\\\""),
                self::BS => self.write_str("\\\\"),
                self::U => {
                    static HEX_DIGITS: [u8; 16] = *b"0123456789abcdef";
                    self.write_str("\\u00");
                    self.write_char(HEX_DIGITS[(byte >> 4) as usize] as char);
                    self.write_char(HEX_DIGITS[(byte & 0xF) as usize] as char);
                }
                _ => unreachable!(),
            }

            start = i + 1;
        }

        if start != bytes.len() {
            self.write_str(&value[start..]);
        }

        self.write_char('"');
    }
}

const BB: u8 = b'b'; // \x08
const TT: u8 = b't'; // \x09
const NN: u8 = b'n'; // \x0A
const FF: u8 = b'f'; // \x0C
const RR: u8 = b'r'; // \x0D
const QU: u8 = b'"'; // \x22
const BS: u8 = b'\\'; // \x5C
const U: u8 = b'u'; // \x00...\x1F except the ones above

// Lookup table of escape sequences. A value of b'x' at index i means that byte
// i is escaped as "\x" in JSON. A value of 0 means that byte i is not escaped.
#[rustfmt::skip]
static ESCAPE: [u8; 256] = [
    //  1   2   3   4   5   6   7   8   9   A   B   C   D   E   F
    U,  U,  U,  U,  U,  U,  U,  U, BB, TT, NN,  U, FF, RR,  U,  U, // 0
    U,  U,  U,  U,  U,  U,  U,  U,  U,  U,  U,  U,  U,  U,  U,  U, // 1
    0,  0, QU,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, // 2
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, // 3
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, // 4
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, BS,  0,  0,  0, // 5
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, // 6
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, // 7
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, // 8
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, // 9
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, // A
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, // B
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, // C
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, // D
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, // E
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, // F
];

/// Serializes a value to JSON.
pub fn to_string(value: &Content) -> String {
    let mut ser = Serializer::new();
    ser.serialize(value);
    ser.into_result()
}

/// Serializes a value to JSON in single-line format.
#[allow(unused)]
pub fn to_string_compact(value: &Content) -> String {
    let mut ser = Serializer::new();
    ser.format = Format::SingleLine;
    ser.serialize(value);
    let rv = ser.into_result();
    // this is pretty wasteful as we just format twice
    // but it's acceptable for the way this is used in
    // insta.
    if rv.chars().count() > COMPACT_MAX_CHARS {
        to_string_pretty(value)
    } else {
        rv
    }
}

/// Serializes a value to JSON pretty
#[allow(unused)]
pub fn to_string_pretty(value: &Content) -> String {
    let mut ser = Serializer::new();
    ser.format = Format::Pretty;
    ser.serialize(value);
    ser.into_result()
}

#[test]
fn test_to_string() {
    let json = to_string(&Content::Map(vec![
        (
            Content::from("environments"),
            Content::Seq(vec![
                Content::from("development"),
                Content::from("production"),
            ]),
        ),
        (Content::from("cmdline"), Content::Seq(vec![])),
        (Content::from("extra"), Content::Map(vec![])),
    ]));
    crate::assert_snapshot!(&json, @r###"{"environments":["development","production"],"cmdline":[],"extra":{}}"###);
}

#[test]
fn test_to_string_pretty() {
    let json = to_string_pretty(&Content::Map(vec![
        (
            Content::from("environments"),
            Content::Seq(vec![
                Content::from("development"),
                Content::from("production"),
            ]),
        ),
        (Content::from("cmdline"), Content::Seq(vec![])),
        (Content::from("extra"), Content::Map(vec![])),
    ]));
    crate::assert_snapshot!(&json, @r###"
    {
      "environments": [
        "development",
        "production"
      ],
      "cmdline": [],
      "extra": {}
    }
    "###);
}

#[test]
fn test_to_string_num_keys() {
    let content = Content::Map(vec![
        (Content::from(42u32), Content::from(true)),
        (Content::from(-23i32), Content::from(false)),
    ]);
    let json = to_string_pretty(&content);
    crate::assert_snapshot!(&json, @r###"
    {
      "42": true,
      "-23": false
    }
    "###);
}

#[test]
fn test_to_string_pretty_complex() {
    let content = Content::Map(vec![
        (
            Content::from("is_alive"),
            Content::NewtypeStruct("Some", Content::from(true).into()),
        ),
        (
            Content::from("newtype_variant"),
            Content::NewtypeVariant(
                "Foo",
                0,
                "variant_a",
                Box::new(Content::Struct(
                    "VariantA",
                    vec![
                        ("field_a", Content::String("value_a".into())),
                        ("field_b", 42u32.into()),
                    ],
                )),
            ),
        ),
        (
            Content::from("struct_variant"),
            Content::StructVariant(
                "Foo",
                0,
                "variant_b",
                vec![
                    ("field_a", Content::String("value_a".into())),
                    ("field_b", 42u32.into()),
                ],
            ),
        ),
        (
            Content::from("tuple_variant"),
            Content::TupleVariant(
                "Foo",
                0,
                "variant_c",
                vec![(Content::String("value_a".into())), (42u32.into())],
            ),
        ),
        (Content::from("empty_array"), Content::Seq(vec![])),
        (Content::from("empty_object"), Content::Map(vec![])),
        (Content::from("array"), Content::Seq(vec![true.into()])),
        (
            Content::from("object"),
            Content::Map(vec![("foo".into(), true.into())]),
        ),
        (
            Content::from("array_of_objects"),
            Content::Seq(vec![Content::Struct(
                "MyType",
                vec![
                    ("foo", Content::from("bar".to_string())),
                    ("bar", Content::from("xxx".to_string())),
                ],
            )]),
        ),
        (
            Content::from("unit_variant"),
            Content::UnitVariant("Stuff", 0, "value"),
        ),
        (Content::from("u8"), Content::U8(8)),
        (Content::from("u16"), Content::U16(16)),
        (Content::from("u32"), Content::U32(32)),
        (Content::from("u64"), Content::U64(64)),
        (Content::from("u128"), Content::U128(128)),
        (Content::from("i8"), Content::I8(8)),
        (Content::from("i16"), Content::I16(16)),
        (Content::from("i32"), Content::I32(32)),
        (Content::from("i64"), Content::I64(64)),
        (Content::from("i128"), Content::I128(128)),
        (Content::from("f32"), Content::F32(32.0)),
        (Content::from("f64"), Content::F64(64.0)),
        (Content::from("char"), Content::Char('A')),
        (Content::from("bytes"), Content::Bytes(b"hehe".to_vec())),
        (Content::from("null"), Content::None),
        (Content::from("unit"), Content::Unit),
        (
            Content::from("crazy_string"),
            Content::String((0u8..=126).map(|x| x as char).collect()),
        ),
    ]);
    let json = to_string_pretty(&content);

    crate::assert_snapshot!(&json, @r###"
    {
      "is_alive": true,
      "newtype_variant": {
        "variant_a": {
          "field_a": "value_a",
          "field_b": 42
        }
      },
      "struct_variant": {
        "variant_b": {
          "field_a": "value_a",
          "field_b": 42
        }
      },
      "tuple_variant": {
        "variant_c": [
          "value_a",
          42
        ]
      },
      "empty_array": [],
      "empty_object": {},
      "array": [
        true
      ],
      "object": {
        "foo": true
      },
      "array_of_objects": [
        {
          "foo": "bar",
          "bar": "xxx"
        }
      ],
      "unit_variant": "value",
      "u8": 8,
      "u16": 16,
      "u32": 32,
      "u64": 64,
      "u128": 128,
      "i8": 8,
      "i16": 16,
      "i32": 32,
      "i64": 64,
      "i128": 128,
      "f32": 32.0,
      "f64": 64.0,
      "char": "A",
      "bytes": [
        104,
        101,
        104,
        101
      ],
      "null": null,
      "unit": null,
      "crazy_string": "\u0000\u0001\u0002\u0003\u0004\u0005\u0006\u0007\b\t\n\u000b\f\r\u000e\u000f\u0010\u0011\u0012\u0013\u0014\u0015\u0016\u0017\u0018\u0019\u001a\u001b\u001c\u001d\u001e\u001f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~"
    }
    "###);
}
