/* Please see LICENSE for licensing information. */

#include <stdlib.h>
#include <stdio.h>

#include "BitVector.h"

#include <assert.h>

int main(int argc, char** argv)
{
    BitVector* bv = bv_new(100);
    assert(bv_size(bv) == 100);
    assert(bv->numBlocks_ == 4);

    bv_set(bv, 2);

    for (int i = 0; i < 100; i++) {
        assert(bv_is_set(bv, i) == (i == 2));
    }

    assert(bv_num_set(bv) == 1);

    bv_set(bv, 99);

    assert(bv_is_set(bv, 99));
    assert(bv_num_set(bv) == 2);

    bv_unset(bv, 2);

    assert(bv_is_set(bv, 2) == 0);
    assert(bv_num_set(bv) == 1);

    bv_clear(bv);
    assert(bv_num_set(bv) == 0);
    assert(bv_is_set(bv, 2) == 0);
    assert(bv_is_set(bv, 99) == 0);

    // now make a random bitvector
    for (int i = 0; i < 50; i++) {
        bv_set(bv, rand() % 90);
    }

    BitVector* bv2 = bv_copy(bv);

    assert(bv_equal(bv, bv2));
    assert(bv_equal(bv2, bv));
    assert(bv_is_subset(bv, bv2));
    assert(bv_is_subset(bv2, bv));

    bv_set(bv2, 90);
    assert(!bv_equal(bv, bv2));
    assert(bv_is_subset(bv, bv2));
    assert(!bv_is_subset(bv2, bv));

    assert(bv_num_set(bv2) == bv_num_set(bv) + 1);

    bv_intersect(bv2, bv);
    assert(bv_equal(bv, bv2));

    bv_delete(bv2);
    bv2 = bv_new(100);
    bv_assign(bv, bv2);
    assert(bv_equal(bv, bv2));

    bv_clear(bv);
    bv_clear(bv2);

    for (int i = 0; i < 10; i++) {
        bv_set(bv, i);
        bv_set(bv2, 10+i);
    }

    assert(bv_num_set(bv) == bv_num_set(bv2));
    assert(bv_num_set(bv) == 10);

    bv_union(bv, bv2);

    assert(bv_num_set(bv) == 20);

    for (int i = 0; i < 20; i++) {
        assert(bv_is_set(bv, i));
    }

    bv_delete(bv);
    bv_delete(bv2);

    return 0;
}