/*
 * 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.
 */
use std::io::Write;
use std::process;
use std::time::SystemTime;

use byteorder::{BigEndian, WriteBytesExt};
use once_cell::sync::Lazy;
use parking_lot::Mutex;
use time::{Date, OffsetDateTime, PrimitiveDateTime, Time};

/**
 * The codec for the message-id.
 *
 * <p>Codec here provides the following two functions:
 * 1. Provide decoding function of message-id of all versions above v0.
 * 2. Provide a generator of message-id of v1 version.
 *
 * <p>The message-id of versions above V1 consists of 17 bytes in total. The first two bytes represent the version
 * number. For V1, these two bytes are 0x0001.
 *
 * <h3>V1 message id example</h3>
 *
 * <pre>
 * ┌──┬────────────┬────┬────────┬────────┐
 * │01│56F7E71C361B│21BC│024CCDBE│00000000│
 * └──┴────────────┴────┴────────┴────────┘
 * </pre>
 *
 * <h3>V1 version message id generation rules</h3>
 *
 * <pre>
 *                     process id(lower 2bytes)
 *                             ▲
 * mac address(lower 6bytes)   │   sequence number(big endian)
 *                    ▲        │          ▲ (4bytes)
 *                    │        │          │
 *              ┌─────┴─────┐ ┌┴┐ ┌───┐ ┌─┴─┐
 *       0x01+  │     6     │ │2│ │ 4 │ │ 4 │
 *              └───────────┘ └─┘ └─┬─┘ └───┘
 *                                  │
 *                                  ▼
 *           seconds since 2021-01-01 00:00:00(UTC+0)
 *                         (lower 4bytes)
 * </pre>
 */

// inspired by https://github.com/messense/rocketmq-rs
pub(crate) static UNIQ_ID_GENERATOR: Lazy<Mutex<UniqueIdGenerator>> = Lazy::new(|| {
    let mut wtr = Vec::new();
    wtr.write_u8(1).unwrap();
    // mac
    let x = mac_address::get_mac_address().unwrap();
    let ma = match x {
        Some(ma) => ma,
        None => {
            panic!("mac address is none")
        }
    };
    wtr.write_all(&ma.bytes()).unwrap();
    // process id
    wtr.write_u16::<BigEndian>(process::id() as u16).unwrap();
    let generator = UniqueIdGenerator {
        counter: 0,
        start_timestamp: 0,
        next_timestamp: 0,
        prefix: hex::encode_upper(wtr),
    };
    Mutex::new(generator)
});

pub struct UniqueIdGenerator {
    counter: i16,
    prefix: String,
    start_timestamp: i64,
    next_timestamp: i64,
}

impl UniqueIdGenerator {
    pub fn next_id(&mut self) -> String {
        if SystemTime::now()
            .duration_since(SystemTime::UNIX_EPOCH)
            .unwrap()
            .as_secs() as i64
            > self.next_timestamp
        {
            // update timestamp
            let now = OffsetDateTime::now_utc();
            let year = now.year();
            let month = now.month();
            self.start_timestamp = PrimitiveDateTime::new(
                Date::from_calendar_date(year, month, 1).unwrap(),
                Time::from_hms(0, 0, 0).unwrap(),
            )
            .assume_offset(now.offset())
            .unix_timestamp();
            self.next_timestamp = (PrimitiveDateTime::new(
                Date::from_calendar_date(year, month, 1).unwrap(),
                Time::from_hms(0, 0, 0).unwrap(),
            )
            .assume_offset(now.offset())
                + time::Duration::days(30))
            .unix_timestamp();
        }
        self.counter = self.counter.wrapping_add(1);
        let mut buf = Vec::new();
        buf.write_i32::<BigEndian>(
            ((OffsetDateTime::now_utc().unix_timestamp() - self.start_timestamp) * 1000) as i32,
        )
        .unwrap();
        buf.write_i16::<BigEndian>(self.counter).unwrap();
        self.prefix.clone() + &hex::encode(buf)
    }
}

#[cfg(test)]
mod test {
    #[test]
    fn text_generate_uniq_id() {
        use super::UNIQ_ID_GENERATOR;
        for i in 0..10 {
            let uid = UNIQ_ID_GENERATOR.lock().next_id();
            println!("i: {}, uid: {}", i, uid);
        }
    }
}
