// 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::hash::Hash;
use std::time::SystemTime;
use rand::RngCore;

pub struct IDGenerator {}

impl IDGenerator {
    /// ID generated by 3 parts
    /// 1. Registered service instance id
    /// 2. thread local level random u64
    /// 3. Timestamp in ms
    pub fn new_id(instance_id: i32) -> ID {
        ID::new(
            instance_id as i64,
            rand::thread_rng().next_u64() as i64,
            SystemTime::now().duration_since(SystemTime::UNIX_EPOCH).ok().unwrap().as_millis() as i64,
        )
    }
}

/// ID is used for trace id and segment id.
/// It is combined by 3 i64 numbers, and could be formatted as `part1.part2.part3` string.
#[derive(Clone, Hash)]
pub struct ID {
    part1: i64,
    part2: i64,
    part3: i64,
}

impl ID {
    pub fn new(part1: i64, part2: i64, part3: i64) -> Self {
        ID {
            part1,
            part2,
            part3,
        }
    }

    /// Convert the literal string text back to ID object.
    /// Return Option::None if the text is not combined by 3 dot split i64 parts
    pub fn from(id_text: String) -> Option<Self> {
        let strings: Vec<&str> = id_text.split(".").collect();
        if strings.len() == 3 {
            let part1 = strings[0].parse::<i64>();
            if part1.is_err() { return None; }
            let part2 = strings[1].parse::<i64>();
            if part2.is_err() { return None; }
            let part3 = strings[2].parse::<i64>();
            if part3.is_err() { return None; }
            Some(ID::new(part1.unwrap(), part2.unwrap(), part3.unwrap()))
        } else {
            None
        }
    }
}

impl PartialEq for ID {
    fn eq(&self, other: &Self) -> bool {
        self.part1 == other.part1 && self.part2 == other.part2 && self.part3 == other.part3
    }
}

impl ToString for ID {
    fn to_string(&self) -> String {
        format!("{}.{}.{}", self.part1, self.part2, self.part3)
    }
}


#[cfg(test)]
mod id_tests {
    use crate::ID;
    use crate::id::IDGenerator;

    #[test]
    fn test_id_generator() {
        let id = IDGenerator::new_id(1);
        assert_eq!(id.part1, 1);
    }

    #[test]
    fn test_id_new() {
        let id1 = ID::new(1, 2, 3);
        let id2 = ID::new(1, 2, 3);
        let id3 = ID::new(1, 2, 4);

        assert_eq!(id1.eq(&id2), true);
        assert_eq!(id1.ne(&id3), true);
        assert_eq!(id1.to_string(), "1.2.3");

        let id4 = ID::from(String::from("1.2.3")).unwrap();
        assert_eq!(id4.eq(&id1), true);

        let id5_none = ID::from(String::from("1.2"));
        assert_eq!(id5_none == None, true);

        let id6_illegal = ID::from(String::from("1.2.a"));
        assert_eq!(id6_illegal == None, true);
    }
}