// Copyright 2013 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 llvm;
use llvm::{UseRef, ValueRef};
use basic_block::BasicBlock;
use common::Block;

use std::fmt;

use libc::c_uint;

#[derive(Copy, Clone, PartialEq)]
pub struct Value(pub ValueRef);

impl fmt::Debug for Value {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.write_str(&llvm::build_string(|s| unsafe {
            llvm::LLVMRustWriteValueToString(self.0, s);
        }).expect("nun-UTF8 value description from LLVM"))
    }
}

macro_rules! opt_val { ($e:expr) => (
    unsafe {
        match $e {
            p if !p.is_null() => Some(Value(p)),
            _ => None
        }
    }
) }

/// Wrapper for LLVM ValueRef
impl Value {
    /// Returns the native ValueRef
    pub fn get(&self) -> ValueRef {
        let Value(v) = *self; v
    }

    /// Returns the BasicBlock that contains this value
    pub fn get_parent(self) -> Option<BasicBlock> {
        unsafe {
            match llvm::LLVMGetInstructionParent(self.get()) {
                p if !p.is_null() => Some(BasicBlock(p)),
                _ => None
            }
        }
    }

    /// Removes this value from its containing BasicBlock
    pub fn erase_from_parent(self) {
        unsafe {
            llvm::LLVMInstructionEraseFromParent(self.get());
        }
    }

    /// Returns the single dominating store to this value, if any
    /// This only performs a search for a trivially dominating store. The store
    /// must be the only user of this value, and there must not be any conditional
    /// branches between the store and the given block.
    pub fn get_dominating_store(self, bcx: Block) -> Option<Value> {
        match self.get_single_user().and_then(|user| user.as_store_inst()) {
            Some(store) => {
                store.get_parent().and_then(|store_bb| {
                    let mut bb = BasicBlock(bcx.llbb);
                    let mut ret = Some(store);
                    while bb.get() != store_bb.get() {
                        match bb.get_single_predecessor() {
                            Some(pred) => bb = pred,
                            None => { ret = None; break }
                        }
                    }
                    ret
                })
            }
            _ => None
        }
    }

    /// Returns the first use of this value, if any
    pub fn get_first_use(self) -> Option<Use> {
        unsafe {
            match llvm::LLVMGetFirstUse(self.get()) {
                u if !u.is_null() => Some(Use(u)),
                _ => None
            }
        }
    }

    /// Tests if there are no uses of this value
    pub fn has_no_uses(self) -> bool {
        self.get_first_use().is_none()
    }

    /// Returns the single user of this value
    /// If there are no users or multiple users, this returns None
    pub fn get_single_user(self) -> Option<Value> {
        let mut iter = self.user_iter();
        match (iter.next(), iter.next()) {
            (Some(first), None) => Some(first),
            _ => None
        }
    }

    /// Returns an iterator for the users of this value
    pub fn user_iter(self) -> Users {
        Users {
            next: self.get_first_use()
        }
    }

    /// Returns the requested operand of this instruction
    /// Returns None, if there's no operand at the given index
    pub fn get_operand(self, i: usize) -> Option<Value> {
        opt_val!(llvm::LLVMGetOperand(self.get(), i as c_uint))
    }

    /// Returns the Store represent by this value, if any
    pub fn as_store_inst(self) -> Option<Value> {
        opt_val!(llvm::LLVMIsAStoreInst(self.get()))
    }

    /// Tests if this value is a terminator instruction
    pub fn is_a_terminator_inst(self) -> bool {
        unsafe {
            !llvm::LLVMIsATerminatorInst(self.get()).is_null()
        }
    }
}

/// Wrapper for LLVM UseRef
#[derive(Copy, Clone)]
pub struct Use(UseRef);

impl Use {
    pub fn get(&self) -> UseRef {
        let Use(v) = *self; v
    }

    pub fn get_user(self) -> Value {
        unsafe {
            Value(llvm::LLVMGetUser(self.get()))
        }
    }

    pub fn get_next_use(self) -> Option<Use> {
        unsafe {
            match llvm::LLVMGetNextUse(self.get()) {
                u if !u.is_null() => Some(Use(u)),
                _ => None
            }
        }
    }
}

/// Iterator for the users of a value
pub struct Users {
    next: Option<Use>
}

impl Iterator for Users {
    type Item = Value;

    fn next(&mut self) -> Option<Value> {
        let current = self.next;

        self.next = current.and_then(|u| u.get_next_use());

        current.map(|u| u.get_user())
    }
}
