// 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.

//! TsBlock decoder — the binary query-result format returned in
//! `queryResult` by the V2 RPCs (protocol spec §5). All integers big-endian.

use super::bitmap::unpack_bits_msb_first;
use super::value::Value;
use super::TSDataType;
use crate::error::{Error, Result};

/// TsBlock column encodings (spec §5.2). `pub(crate)` so the dataset tests
/// can craft synthetic blocks with the same constants.
pub(crate) const ENCODING_BYTE_ARRAY: u8 = 0;
pub(crate) const ENCODING_INT32_ARRAY: u8 = 1;
pub(crate) const ENCODING_INT64_ARRAY: u8 = 2;
pub(crate) const ENCODING_BINARY_ARRAY: u8 = 3;
pub(crate) const ENCODING_RLE: u8 = 4;

/// One decoded TsBlock: `position_count` rows of a time column plus
/// `columns.len()` value columns. Null cells are [`Value::Null`].
#[derive(Debug, Clone, PartialEq)]
pub struct TsBlock {
    pub position_count: usize,
    pub column_types: Vec<TSDataType>,
    /// Time column, always present on the wire — the caller drops it when
    /// `ignoreTimeStamp` is set (spec gotcha #10).
    pub timestamps: Vec<i64>,
    /// `columns[col][row]`; nulls decoded as [`Value::Null`].
    pub columns: Vec<Vec<Value>>,
}

impl TsBlock {
    /// Decodes one serialized TsBlock (one element of `queryResult`).
    ///
    /// Layout (spec §5.1): `valueColumnCount` i32, per-column type bytes,
    /// `positionCount` i32, time-column encoding byte, per-column encoding
    /// bytes, then the time column followed by each value column.
    pub fn decode(bytes: &[u8]) -> Result<TsBlock> {
        let mut r = Reader::new(bytes);

        let value_column_count = r.read_i32()?;
        if value_column_count < 0 {
            return Err(Error::Decode(format!(
                "negative valueColumnCount: {value_column_count}"
            )));
        }
        let value_column_count = value_column_count as usize;

        let mut column_types = Vec::with_capacity(value_column_count);
        for _ in 0..value_column_count {
            let code = r.read_u8()?;
            column_types.push(
                TSDataType::from_code(code)
                    .ok_or_else(|| Error::Decode(format!("unknown TSDataType code {code}")))?,
            );
        }

        let position_count = r.read_i32()?;
        if position_count < 0 {
            return Err(Error::Decode(format!(
                "negative positionCount: {position_count}"
            )));
        }
        let position_count = position_count as usize;

        let time_encoding = r.read_u8()?;
        let mut value_encodings = Vec::with_capacity(value_column_count);
        for _ in 0..value_column_count {
            value_encodings.push(r.read_u8()?);
        }

        // Time column is always present (gotcha #10); decoded as INT64.
        let time_column = decode_column(&mut r, time_encoding, TSDataType::Int64, position_count)?;
        let mut timestamps = Vec::with_capacity(position_count);
        for v in time_column {
            match v {
                Value::Int64(t) => timestamps.push(t),
                other => {
                    return Err(Error::Decode(format!(
                        "time column contains non-INT64 value: {other:?}"
                    )))
                }
            }
        }

        let mut columns = Vec::with_capacity(value_column_count);
        for (i, &ty) in column_types.iter().enumerate() {
            columns.push(decode_column(
                &mut r,
                value_encodings[i],
                ty,
                position_count,
            )?);
        }

        Ok(TsBlock {
            position_count,
            column_types,
            timestamps,
            columns,
        })
    }
}

/// Decodes one column body: null-indicator section, then encoding-specific
/// values (spec §5.3).
fn decode_column(
    r: &mut Reader<'_>,
    encoding: u8,
    ty: TSDataType,
    position_count: usize,
) -> Result<Vec<Value>> {
    match encoding {
        ENCODING_RLE => {
            // Inner-encoding byte, decode ONE value, replicate.
            let inner = r.read_u8()?;
            if inner == ENCODING_RLE {
                return Err(Error::Decode("nested RLE column encoding".into()));
            }
            let single = decode_column(r, inner, ty, 1)?;
            let v = single
                .into_iter()
                .next()
                .ok_or_else(|| Error::Decode("empty RLE inner column".into()))?;
            Ok(vec![v; position_count])
        }
        ENCODING_BYTE_ARRAY => {
            let nulls = read_null_indicators(r, position_count)?;
            // BOOLEAN values: full positionCount bit array (MSB-first),
            // NOT null-skipped — unlike the numeric encodings.
            let bits = read_packed_bits(r, position_count)?;
            Ok((0..position_count)
                .map(|i| {
                    if nulls[i] {
                        Value::Null
                    } else {
                        Value::Boolean(bits[i])
                    }
                })
                .collect())
        }
        ENCODING_INT32_ARRAY => {
            let nulls = read_null_indicators(r, position_count)?;
            let mut out = Vec::with_capacity(position_count);
            for &is_null in &nulls {
                if is_null {
                    out.push(Value::Null);
                    continue; // dense: null positions consume no bytes
                }
                let raw = r.read_i32()?;
                out.push(match ty {
                    TSDataType::Int32 => Value::Int32(raw),
                    TSDataType::Date => Value::Date(raw),
                    TSDataType::Float => Value::Float(f32::from_bits(raw as u32)),
                    _ => {
                        return Err(Error::Decode(format!(
                            "Int32Array encoding with incompatible type {ty:?}"
                        )))
                    }
                });
            }
            Ok(out)
        }
        ENCODING_INT64_ARRAY => {
            let nulls = read_null_indicators(r, position_count)?;
            let mut out = Vec::with_capacity(position_count);
            for &is_null in &nulls {
                if is_null {
                    out.push(Value::Null);
                    continue;
                }
                let raw = r.read_i64()?;
                out.push(match ty {
                    TSDataType::Int64 => Value::Int64(raw),
                    TSDataType::Timestamp => Value::Timestamp(raw),
                    TSDataType::Double => Value::Double(f64::from_bits(raw as u64)),
                    _ => {
                        return Err(Error::Decode(format!(
                            "Int64Array encoding with incompatible type {ty:?}"
                        )))
                    }
                });
            }
            Ok(out)
        }
        ENCODING_BINARY_ARRAY => {
            let nulls = read_null_indicators(r, position_count)?;
            let mut out = Vec::with_capacity(position_count);
            for &is_null in &nulls {
                if is_null {
                    out.push(Value::Null);
                    continue;
                }
                let len = r.read_i32()?;
                if len < 0 {
                    return Err(Error::Decode(format!("negative binary length: {len}")));
                }
                let bytes = r.read_bytes(len as usize)?.to_vec();
                out.push(match ty {
                    TSDataType::Blob => Value::Blob(bytes),
                    // TsBlock headers carry the *physical* type: BLOB columns
                    // arrive typed TEXT here. Keep non-UTF-8 payloads as Blob
                    // so row assembly can re-tag them via the response's
                    // logical dataTypeList (same pattern as DATE/INT32).
                    TSDataType::Text => match String::from_utf8(bytes) {
                        Ok(s) => Value::Text(s),
                        Err(e) => Value::Blob(e.into_bytes()),
                    },
                    TSDataType::String => Value::String(decode_utf8(bytes)?),
                    _ => {
                        return Err(Error::Decode(format!(
                            "BinaryArray encoding with incompatible type {ty:?}"
                        )))
                    }
                });
            }
            Ok(out)
        }
        other => Err(Error::Decode(format!("unknown column encoding {other}"))),
    }
}

/// Null-indicator section: 1 byte `mayHaveNull`; if non-zero, a
/// `ceil(positionCount/8)`-byte MSB-first bitmap with bit=1 ⇒ null.
fn read_null_indicators(r: &mut Reader<'_>, position_count: usize) -> Result<Vec<bool>> {
    let may_have_null = r.read_u8()?;
    if may_have_null == 0 {
        return Ok(vec![false; position_count]);
    }
    read_packed_bits(r, position_count)
}

/// Reads `count` MSB-first packed bits (`ceil(count/8)` bytes).
fn read_packed_bits(r: &mut Reader<'_>, count: usize) -> Result<Vec<bool>> {
    let bytes = r.read_bytes(count.div_ceil(8))?;
    unpack_bits_msb_first(bytes, count)
        .ok_or_else(|| Error::Decode("truncated packed bit array".into()))
}

fn decode_utf8(bytes: Vec<u8>) -> Result<String> {
    String::from_utf8(bytes)
        .map_err(|e| Error::Decode(format!("invalid UTF-8 in text column: {e}")))
}

/// Bounds-checked big-endian cursor over a byte slice.
struct Reader<'a> {
    buf: &'a [u8],
    pos: usize,
}

impl<'a> Reader<'a> {
    fn new(buf: &'a [u8]) -> Reader<'a> {
        Reader { buf, pos: 0 }
    }

    fn read_bytes(&mut self, n: usize) -> Result<&'a [u8]> {
        let end = self
            .pos
            .checked_add(n)
            .filter(|&e| e <= self.buf.len())
            .ok_or_else(|| {
                Error::Decode(format!(
                    "truncated TsBlock: need {n} bytes at offset {}, have {}",
                    self.pos,
                    self.buf.len() - self.pos
                ))
            })?;
        let slice = &self.buf[self.pos..end];
        self.pos = end;
        Ok(slice)
    }

    fn read_u8(&mut self) -> Result<u8> {
        Ok(self.read_bytes(1)?[0])
    }

    fn read_i32(&mut self) -> Result<i32> {
        let b = self.read_bytes(4)?;
        Ok(i32::from_be_bytes([b[0], b[1], b[2], b[3]]))
    }

    fn read_i64(&mut self) -> Result<i64> {
        let b = self.read_bytes(8)?;
        Ok(i64::from_be_bytes([
            b[0], b[1], b[2], b[3], b[4], b[5], b[6], b[7],
        ]))
    }
}

/// Encoding helpers for crafting synthetic TsBlocks in unit tests (shared
/// with the dataset state-machine tests).
#[cfg(test)]
pub(crate) mod test_util {
    use super::*;

    /// Builds a TsBlock header: valueColumnCount, type bytes, positionCount,
    /// time encoding (Int64Array), value encodings.
    pub(crate) fn header(types: &[TSDataType], position_count: i32, encodings: &[u8]) -> Vec<u8> {
        let mut b = Vec::new();
        b.extend_from_slice(&(types.len() as i32).to_be_bytes());
        for &t in types {
            b.push(t.code() as u8);
        }
        b.extend_from_slice(&position_count.to_be_bytes());
        b.push(ENCODING_INT64_ARRAY); // time column
        b.extend_from_slice(encodings);
        b
    }

    /// Dense Int64Array time column with no nulls.
    pub(crate) fn time_column(ts: &[i64]) -> Vec<u8> {
        let mut b = vec![0u8]; // mayHaveNull = 0
        for t in ts {
            b.extend_from_slice(&t.to_be_bytes());
        }
        b
    }

    /// One-Int32-column block: timestamps `ts`, dense non-null values `vals`.
    pub(crate) fn int32_block(ts: &[i64], vals: &[i32]) -> Vec<u8> {
        assert_eq!(ts.len(), vals.len());
        let mut b = header(
            &[TSDataType::Int32],
            ts.len() as i32,
            &[ENCODING_INT32_ARRAY],
        );
        b.extend_from_slice(&time_column(ts));
        b.push(0); // mayHaveNull
        for v in vals {
            b.extend_from_slice(&v.to_be_bytes());
        }
        b
    }
}

#[cfg(test)]
mod tests {
    use super::test_util::{header, time_column};
    use super::*;

    #[test]
    fn int32_column_no_nulls() {
        let mut b = header(&[TSDataType::Int32], 2, &[ENCODING_INT32_ARRAY]);
        b.extend_from_slice(&time_column(&[10, 20]));
        b.push(0); // mayHaveNull
        b.extend_from_slice(&5i32.to_be_bytes());
        b.extend_from_slice(&(-1i32).to_be_bytes());

        let block = TsBlock::decode(&b).unwrap();
        assert_eq!(block.position_count, 2);
        assert_eq!(block.timestamps, vec![10, 20]);
        assert_eq!(block.column_types, vec![TSDataType::Int32]);
        assert_eq!(block.columns, vec![vec![Value::Int32(5), Value::Int32(-1)]]);
    }

    #[test]
    fn nulls_are_dense_skipped_in_numeric_columns() {
        // 3 rows, row 1 null: only 2 i32 values on the wire.
        let mut b = header(&[TSDataType::Int32], 3, &[ENCODING_INT32_ARRAY]);
        b.extend_from_slice(&time_column(&[1, 2, 3]));
        b.push(1); // mayHaveNull
        b.push(0b0100_0000); // MSB-first: position 1 null
        b.extend_from_slice(&7i32.to_be_bytes());
        b.extend_from_slice(&9i32.to_be_bytes());

        let block = TsBlock::decode(&b).unwrap();
        assert_eq!(
            block.columns[0],
            vec![Value::Int32(7), Value::Null, Value::Int32(9)]
        );
    }

    #[test]
    fn int64_double_and_float_bit_patterns() {
        let types = [TSDataType::Double, TSDataType::Float, TSDataType::Timestamp];
        let mut b = header(
            &types,
            1,
            &[
                ENCODING_INT64_ARRAY,
                ENCODING_INT32_ARRAY,
                ENCODING_INT64_ARRAY,
            ],
        );
        b.extend_from_slice(&time_column(&[42]));
        b.push(0);
        b.extend_from_slice(&(-2.5f64).to_be_bytes()); // f64 via i64 bits
        b.push(0);
        b.extend_from_slice(&1.5f32.to_be_bytes());
        b.push(0);
        b.extend_from_slice(&123456789012345i64.to_be_bytes());

        let block = TsBlock::decode(&b).unwrap();
        assert_eq!(block.columns[0], vec![Value::Double(-2.5)]);
        assert_eq!(block.columns[1], vec![Value::Float(1.5)]);
        assert_eq!(block.columns[2], vec![Value::Timestamp(123456789012345)]);
    }

    #[test]
    fn boolean_bytearray_full_bit_array_with_nulls() {
        // 10 rows: nulls at 0 and 9; values MSB-first over ALL positions.
        let mut b = header(&[TSDataType::Boolean], 10, &[ENCODING_BYTE_ARRAY]);
        b.extend_from_slice(&time_column(&(0..10).collect::<Vec<i64>>()));
        b.push(1); // mayHaveNull
        b.extend_from_slice(&[0b1000_0000, 0b0100_0000]); // nulls at 0, 9
                                                          // Value bits (positions 1..=8 meaningful): true at 1, 3, 8.
        b.extend_from_slice(&[0b0101_0000, 0b1000_0000]);

        let block = TsBlock::decode(&b).unwrap();
        let expect: Vec<Value> = vec![
            Value::Null,
            Value::Boolean(true),
            Value::Boolean(false),
            Value::Boolean(true),
            Value::Boolean(false),
            Value::Boolean(false),
            Value::Boolean(false),
            Value::Boolean(false),
            Value::Boolean(true),
            Value::Null,
        ];
        assert_eq!(block.columns[0], expect);
    }

    #[test]
    fn binary_array_text_blob_and_nulls() {
        let types = [TSDataType::Text, TSDataType::Blob];
        let mut b = header(&types, 2, &[ENCODING_BINARY_ARRAY, ENCODING_BINARY_ARRAY]);
        b.extend_from_slice(&time_column(&[1, 2]));
        // Text column: ["héllo", null] — null consumes no bytes.
        b.push(1);
        b.push(0b0100_0000);
        let s = "héllo".as_bytes();
        b.extend_from_slice(&(s.len() as i32).to_be_bytes());
        b.extend_from_slice(s);
        // Blob column, no nulls.
        b.push(0);
        b.extend_from_slice(&2i32.to_be_bytes());
        b.extend_from_slice(&[0xCA, 0xFE]);
        b.extend_from_slice(&0i32.to_be_bytes()); // empty blob

        let block = TsBlock::decode(&b).unwrap();
        assert_eq!(
            block.columns[0],
            vec![Value::Text("héllo".into()), Value::Null]
        );
        assert_eq!(
            block.columns[1],
            vec![Value::Blob(vec![0xCA, 0xFE]), Value::Blob(vec![])]
        );
    }

    #[test]
    fn rle_replicates_single_value() {
        let mut b = header(&[TSDataType::Int64], 4, &[ENCODING_RLE]);
        b.extend_from_slice(&time_column(&[1, 2, 3, 4]));
        b.push(ENCODING_INT64_ARRAY); // inner encoding
        b.push(0); // inner mayHaveNull
        b.extend_from_slice(&99i64.to_be_bytes());

        let block = TsBlock::decode(&b).unwrap();
        assert_eq!(block.columns[0], vec![Value::Int64(99); 4]);
    }

    #[test]
    fn rle_of_null_replicates_null() {
        let mut b = header(&[TSDataType::Int32], 3, &[ENCODING_RLE]);
        b.extend_from_slice(&time_column(&[1, 2, 3]));
        b.push(ENCODING_INT32_ARRAY);
        b.push(1); // inner mayHaveNull
        b.push(0b1000_0000); // single position, null → zero dense values
        let block = TsBlock::decode(&b).unwrap();
        assert_eq!(block.columns[0], vec![Value::Null; 3]);
    }

    #[test]
    fn rle_time_column() {
        // Constant time column via RLE (encoding byte in header slot).
        let mut b = Vec::new();
        b.extend_from_slice(&0i32.to_be_bytes()); // no value columns
        b.extend_from_slice(&3i32.to_be_bytes()); // positionCount
        b.push(ENCODING_RLE); // time encoding
        b.push(ENCODING_INT64_ARRAY); // inner
        b.push(0);
        b.extend_from_slice(&7i64.to_be_bytes());

        let block = TsBlock::decode(&b).unwrap();
        assert_eq!(block.timestamps, vec![7, 7, 7]);
        assert!(block.columns.is_empty());
    }

    #[test]
    fn date_decodes_as_yyyymmdd_i32() {
        let mut b = header(&[TSDataType::Date], 1, &[ENCODING_INT32_ARRAY]);
        b.extend_from_slice(&time_column(&[0]));
        b.push(0);
        b.extend_from_slice(&20260710i32.to_be_bytes());
        let block = TsBlock::decode(&b).unwrap();
        assert_eq!(block.columns[0], vec![Value::Date(20260710)]);
    }

    #[test]
    fn empty_block() {
        let mut b = header(&[TSDataType::Int32], 0, &[ENCODING_INT32_ARRAY]);
        b.extend_from_slice(&time_column(&[]));
        b.push(0); // value column: mayHaveNull, zero values
        let block = TsBlock::decode(&b).unwrap();
        assert_eq!(block.position_count, 0);
        assert!(block.timestamps.is_empty());
        assert_eq!(block.columns, vec![Vec::<Value>::new()]);
    }

    #[test]
    fn truncated_and_malformed_inputs_error() {
        // Truncated header.
        assert!(matches!(TsBlock::decode(&[0, 0]), Err(Error::Decode(_))));
        // Unknown type code.
        let mut b = Vec::new();
        b.extend_from_slice(&1i32.to_be_bytes());
        b.push(200);
        assert!(matches!(TsBlock::decode(&b), Err(Error::Decode(_))));
        // Unknown encoding.
        let mut b = header(&[TSDataType::Int32], 1, &[9]);
        b.extend_from_slice(&time_column(&[1]));
        assert!(matches!(TsBlock::decode(&b), Err(Error::Decode(_))));
        // Truncated value payload.
        let mut b = header(&[TSDataType::Int64], 1, &[ENCODING_INT64_ARRAY]);
        b.extend_from_slice(&time_column(&[1]));
        b.push(0);
        b.extend_from_slice(&[0, 0]); // only 2 of 8 bytes
        assert!(matches!(TsBlock::decode(&b), Err(Error::Decode(_))));
        // Nested RLE is rejected.
        let mut b = header(&[TSDataType::Int32], 1, &[ENCODING_RLE]);
        b.extend_from_slice(&time_column(&[1]));
        b.push(ENCODING_RLE);
        assert!(matches!(TsBlock::decode(&b), Err(Error::Decode(_))));
    }
}
