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

use rustc::hir::def_id::{DefId, DefIndex};
use rbml;
use std::io::{Cursor, Write};
use std::slice;
use std::u32;

/// As part of the metadata, we generate an index that stores, for
/// each DefIndex, the position of the corresponding RBML document (if
/// any).  This is just a big `[u32]` slice, where an entry of
/// `u32::MAX` indicates that there is no RBML document. This little
/// struct just stores the offsets within the metadata of the start
/// and end of this slice. These are actually part of an RBML
/// document, but for looking things up in the metadata, we just
/// discard the RBML positioning and jump directly to the data.
pub struct Index {
    data_start: usize,
    data_end: usize,
}

impl Index {
    /// Given the RBML doc representing the index, save the offests
    /// for later.
    pub fn from_rbml(index: rbml::Doc) -> Index {
        Index { data_start: index.start, data_end: index.end }
    }

    /// Given the metadata, extract out the offset of a particular
    /// DefIndex (if any).
    #[inline(never)]
    pub fn lookup_item(&self, bytes: &[u8], def_index: DefIndex) -> Option<u32> {
        let words = bytes_to_words(&bytes[self.data_start..self.data_end]);
        let index = def_index.as_usize();

        debug!("lookup_item: index={:?} words.len={:?}",
               index, words.len());

        let position = u32::from_be(words[index]);
        if position == u32::MAX {
            debug!("lookup_item: position=u32::MAX");
            None
        } else {
            debug!("lookup_item: position={:?}", position);
            Some(position)
        }
    }
}

/// While we are generating the metadata, we also track the position
/// of each DefIndex. It is not required that all definitions appear
/// in the metadata, nor that they are serialized in order, and
/// therefore we first allocate the vector here and fill it with
/// `u32::MAX`. Whenever an index is visited, we fill in the
/// appropriate spot by calling `record_position`. We should never
/// visit the same index twice.
pub struct IndexData {
    positions: Vec<u32>,
}

impl IndexData {
    pub fn new(max_index: usize) -> IndexData {
        IndexData {
            positions: vec![u32::MAX; max_index]
        }
    }

    pub fn record(&mut self, def_id: DefId, position: u64) {
        assert!(def_id.is_local());
        self.record_index(def_id.index, position);
    }

    pub fn record_index(&mut self, item: DefIndex, position: u64) {
        let item = item.as_usize();

        assert!(position < (u32::MAX as u64));
        let position = position as u32;

        assert!(self.positions[item] == u32::MAX,
                "recorded position for item {:?} twice, first at {:?} and now at {:?}",
                item, self.positions[item], position);

        self.positions[item] = position;
    }

    pub fn write_index(&self, buf: &mut Cursor<Vec<u8>>) {
        for &position in &self.positions {
            write_be_u32(buf, position);
        }
    }
}

/// A dense index with integer keys. Different API from IndexData (should
/// these be merged?)
pub struct DenseIndex {
    start: usize,
    end: usize
}

impl DenseIndex {
    pub fn lookup(&self, buf: &[u8], ix: u32) -> Option<u32> {
        let data = bytes_to_words(&buf[self.start..self.end]);
        data.get(ix as usize).map(|d| u32::from_be(*d))
    }
    pub fn from_buf(buf: &[u8], start: usize, end: usize) -> Self {
        assert!((end-start)%4 == 0 && start <= end && end <= buf.len());
        DenseIndex {
            start: start,
            end: end
        }
    }
}

pub fn write_dense_index(entries: Vec<u32>, buf: &mut Cursor<Vec<u8>>) {
    let elen = entries.len();
    assert!(elen < u32::MAX as usize);

    for entry in entries {
        write_be_u32(buf, entry);
    }

    info!("write_dense_index: {} entries", elen);
}

fn write_be_u32<W: Write>(w: &mut W, u: u32) {
    let _ = w.write_all(&[
        (u >> 24) as u8,
        (u >> 16) as u8,
        (u >>  8) as u8,
        (u >>  0) as u8,
    ]);
}

fn bytes_to_words(b: &[u8]) -> &[u32] {
    assert!(b.len() % 4 == 0);
    unsafe { slice::from_raw_parts(b.as_ptr() as *const u32, b.len()/4) }
}
