// Copyright 2016 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 context::SharedCrateContext;
use monomorphize::Instance;
use rustc::ty::TyCtxt;
use std::borrow::Cow;
use syntax::codemap::Span;
use trans_item::TransItem;
use util::nodemap::FnvHashMap;

// In the SymbolMap we collect the symbol names of all translation items of
// the current crate. This map exists as a performance optimization. Symbol
// names of translation items are deterministic and fully defined by the item.
// Thus they could also always be recomputed if needed.

pub struct SymbolMap<'tcx> {
    index: FnvHashMap<TransItem<'tcx>, (usize, usize)>,
    arena: String,
}

impl<'tcx> SymbolMap<'tcx> {

    pub fn build<'a, I>(scx: &SharedCrateContext<'a, 'tcx>,
                        trans_items: I)
                        -> SymbolMap<'tcx>
        where I: Iterator<Item=TransItem<'tcx>>
    {
        // Check for duplicate symbol names
        let mut symbols: Vec<_> = trans_items.map(|trans_item| {
            (trans_item, trans_item.compute_symbol_name(scx))
        }).collect();

        (&mut symbols[..]).sort_by(|&(_, ref sym1), &(_, ref sym2)|{
            sym1.cmp(sym2)
        });

        for pair in (&symbols[..]).windows(2) {
            let sym1 = &pair[0].1;
            let sym2 = &pair[1].1;

            if *sym1 == *sym2 {
                let trans_item1 = pair[0].0;
                let trans_item2 = pair[1].0;

                let span1 = get_span(scx.tcx(), trans_item1);
                let span2 = get_span(scx.tcx(), trans_item2);

                // Deterministically select one of the spans for error reporting
                let span = match (span1, span2) {
                    (Some(span1), Some(span2)) => {
                        Some(if span1.lo.0 > span2.lo.0 {
                            span1
                        } else {
                            span2
                        })
                    }
                    (Some(span), None) |
                    (None, Some(span)) => Some(span),
                    _ => None
                };

                let error_message = format!("symbol `{}` is already defined", sym1);

                if let Some(span) = span {
                    scx.sess().span_fatal(span, &error_message)
                } else {
                    scx.sess().fatal(&error_message)
                }
            }
        }

        let mut symbol_map = SymbolMap {
            index: FnvHashMap(),
            arena: String::with_capacity(1024),
        };

        for (trans_item, symbol) in symbols {
            let start_index = symbol_map.arena.len();
            symbol_map.arena.push_str(&symbol[..]);
            let end_index = symbol_map.arena.len();
            let prev_entry = symbol_map.index.insert(trans_item,
                                                     (start_index, end_index));
            if prev_entry.is_some() {
                bug!("TransItem encountered twice?")
            }
        }

        fn get_span<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                              trans_item: TransItem<'tcx>) -> Option<Span> {
            match trans_item {
                TransItem::Fn(Instance { def, .. }) => {
                    tcx.map.as_local_node_id(def)
                }
                TransItem::Static(node_id) => Some(node_id),
                TransItem::DropGlue(_) => None,
            }.map(|node_id| {
                tcx.map.span(node_id)
            })
        }

        symbol_map
    }

    pub fn get(&self, trans_item: TransItem<'tcx>) -> Option<&str> {
        self.index.get(&trans_item).map(|&(start_index, end_index)| {
            &self.arena[start_index .. end_index]
        })
    }

    pub fn get_or_compute<'map, 'scx>(&'map self,
                                      scx: &SharedCrateContext<'scx, 'tcx>,
                                      trans_item: TransItem<'tcx>)
                                      -> Cow<'map, str> {
        if let Some(sym) = self.get(trans_item) {
            Cow::from(sym)
        } else {
            Cow::from(trans_item.compute_symbol_name(scx))
        }
    }
}
