// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

/// A very simple BitVector type.
pub struct BitVector {
    data: Vec<u64>
}

impl BitVector {
    pub fn new(num_bits: usize) -> BitVector {
        let num_words = u64s(num_bits);
        BitVector { data: vec![0; num_words] }
    }

    pub fn contains(&self, bit: usize) -> bool {
        let (word, mask) = word_mask(bit);
        (self.data[word] & mask) != 0
    }

    pub fn insert(&mut self, bit: usize) -> bool {
        let (word, mask) = word_mask(bit);
        let data = &mut self.data[word];
        let value = *data;
        *data = value | mask;
        (value | mask) != value
    }

    pub fn insert_all(&mut self, all: &BitVector) -> bool {
        assert!(self.data.len() == all.data.len());
        let mut changed = false;
        for (i, j) in self.data.iter_mut().zip(&all.data) {
            let value = *i;
            *i = value | *j;
            if value != *i { changed = true; }
        }
        changed
    }

    pub fn grow(&mut self, num_bits: usize) {
        let num_words = u64s(num_bits);
        let extra_words = self.data.len() - num_words;
        self.data.extend((0..extra_words).map(|_| 0));
    }
}

/// A "bit matrix" is basically a square matrix of booleans
/// represented as one gigantic bitvector. In other words, it is as if
/// you have N bitvectors, each of length N. Note that `elements` here is `N`/
#[derive(Clone)]
pub struct BitMatrix {
    elements: usize,
    vector: Vec<u64>,
}

impl BitMatrix {
    // Create a new `elements x elements` matrix, initially empty.
    pub fn new(elements: usize) -> BitMatrix {
        // For every element, we need one bit for every other
        // element. Round up to an even number of u64s.
        let u64s_per_elem = u64s(elements);
        BitMatrix {
            elements: elements,
            vector: vec![0; elements * u64s_per_elem]
        }
    }

    /// The range of bits for a given element.
    fn range(&self, element: usize) -> (usize, usize) {
        let u64s_per_elem = u64s(self.elements);
        let start = element * u64s_per_elem;
        (start, start + u64s_per_elem)
    }

    pub fn add(&mut self, source: usize, target: usize) -> bool {
        let (start, _) = self.range(source);
        let (word, mask) = word_mask(target);
        let mut vector = &mut self.vector[..];
        let v1 = vector[start+word];
        let v2 = v1 | mask;
        vector[start+word] = v2;
        v1 != v2
    }

    /// Do the bits from `source` contain `target`?
    ///
    /// Put another way, if the matrix represents (transitive)
    /// reachability, can `source` reach `target`?
    pub fn contains(&self, source: usize, target: usize) -> bool {
        let (start, _) = self.range(source);
        let (word, mask) = word_mask(target);
        (self.vector[start+word] & mask) != 0
    }

    /// Returns those indices that are reachable from both `a` and
    /// `b`. This is an O(n) operation where `n` is the number of
    /// elements (somewhat independent from the actual size of the
    /// intersection, in particular).
    pub fn intersection(&self, a: usize, b: usize) -> Vec<usize> {
        let (a_start, a_end) = self.range(a);
        let (b_start, b_end) = self.range(b);
        let mut result = Vec::with_capacity(self.elements);
        for (base, (i, j)) in (a_start..a_end).zip(b_start..b_end).enumerate() {
            let mut v = self.vector[i] & self.vector[j];
            for bit in 0..64 {
                if v == 0 { break; }
                if v & 0x1 != 0 { result.push(base*64 + bit); }
                v >>= 1;
            }
        }
        result
    }

    /// Add the bits from `read` to the bits from `write`,
    /// return true if anything changed.
    ///
    /// This is used when computing transitive reachability because if
    /// you have an edge `write -> read`, because in that case
    /// `write` can reach everything that `read` can (and
    /// potentially more).
    pub fn merge(&mut self, read: usize, write: usize) -> bool {
        let (read_start, read_end) = self.range(read);
        let (write_start, write_end) = self.range(write);
        let vector = &mut self.vector[..];
        let mut changed = false;
        for (read_index, write_index) in
            (read_start..read_end).zip(write_start..write_end)
        {
            let v1 = vector[write_index];
            let v2 = v1 | vector[read_index];
            vector[write_index] = v2;
            changed = changed | (v1 != v2);
        }
        changed
    }
}

fn u64s(elements: usize) -> usize {
    (elements + 63) / 64
}

fn word_mask(index: usize) -> (usize, u64) {
    let word = index / 64;
    let mask = 1 << (index % 64);
    (word, mask)
}

#[test]
fn union_two_vecs() {
    let mut vec1 = BitVector::new(65);
    let mut vec2 = BitVector::new(65);
    assert!(vec1.insert(3));
    assert!(!vec1.insert(3));
    assert!(vec2.insert(5));
    assert!(vec2.insert(64));
    assert!(vec1.insert_all(&vec2));
    assert!(!vec1.insert_all(&vec2));
    assert!(vec1.contains(3));
    assert!(!vec1.contains(4));
    assert!(vec1.contains(5));
    assert!(!vec1.contains(63));
    assert!(vec1.contains(64));
}

#[test]
fn grow() {
    let mut vec1 = BitVector::new(65);
    assert!(vec1.insert(3));
    assert!(!vec1.insert(3));
    assert!(vec1.insert(5));
    assert!(vec1.insert(64));
    vec1.grow(128);
    assert!(vec1.contains(3));
    assert!(vec1.contains(5));
    assert!(vec1.contains(64));
    assert!(!vec1.contains(126));
}

#[test]
fn matrix_intersection() {
    let mut vec1 = BitMatrix::new(200);

    // (*) Elements reachable from both 2 and 65.

    vec1.add(2, 3);
    vec1.add(2, 6);
    vec1.add(2, 10); // (*)
    vec1.add(2, 64); // (*)
    vec1.add(2, 65);
    vec1.add(2, 130);
    vec1.add(2, 160); // (*)

    vec1.add(64, 133);

    vec1.add(65, 2);
    vec1.add(65, 8);
    vec1.add(65, 10); // (*)
    vec1.add(65, 64); // (*)
    vec1.add(65, 68);
    vec1.add(65, 133);
    vec1.add(65, 160); // (*)

    let intersection = vec1.intersection(2, 64);
    assert!(intersection.is_empty());

    let intersection = vec1.intersection(2, 65);
    assert_eq!(intersection, &[10, 64, 160]);
}
