use crate::interface::{Compiler, Result};
use crate::passes::{self, BoxedResolver, ExpansionResult, BoxedGlobalCtxt, PluginInfo};

use rustc_incremental::DepGraphFuture;
use rustc::session::config::{OutputFilenames, OutputType};
use rustc::util::common::{time, ErrorReported};
use rustc::hir;
use rustc::hir::def_id::LOCAL_CRATE;
use rustc::ty::steal::Steal;
use rustc::dep_graph::DepGraph;
use std::cell::{Ref, RefMut, RefCell};
use std::rc::Rc;
use std::sync::mpsc;
use std::any::Any;
use std::mem;
use syntax::{self, ast};

/// Represent the result of a query.
/// This result can be stolen with the `take` method and returned with the `give` method.
pub struct Query<T> {
    result: RefCell<Option<Result<T>>>,
}

impl<T> Query<T> {
    fn compute<F: FnOnce() -> Result<T>>(&self, f: F) -> Result<&Query<T>> {
        let mut result = self.result.borrow_mut();
        if result.is_none() {
            *result = Some(f());
        }
        result.as_ref().unwrap().as_ref().map(|_| self).map_err(|err| *err)
    }

    /// Takes ownership of the query result. Further attempts to take or peek the query
    /// result will panic unless it is returned by calling the `give` method.
    pub fn take(&self) -> T {
        self.result
            .borrow_mut()
            .take()
            .expect("missing query result")
            .unwrap()
    }

    /// Returns a stolen query result. Panics if there's already a result.
    pub fn give(&self, value: T) {
        let mut result = self.result.borrow_mut();
        assert!(result.is_none(), "a result already exists");
        *result = Some(Ok(value));
    }

    /// Borrows the query result using the RefCell. Panics if the result is stolen.
    pub fn peek(&self) -> Ref<'_, T> {
        Ref::map(self.result.borrow(), |r| {
            r.as_ref().unwrap().as_ref().expect("missing query result")
        })
    }

    /// Mutably borrows the query result using the RefCell. Panics if the result is stolen.
    pub fn peek_mut(&self) -> RefMut<'_, T> {
        RefMut::map(self.result.borrow_mut(), |r| {
            r.as_mut().unwrap().as_mut().expect("missing query result")
        })
    }
}

impl<T> Default for Query<T> {
    fn default() -> Self {
        Query {
            result: RefCell::new(None),
        }
    }
}

#[derive(Default)]
pub(crate) struct Queries {
    dep_graph_future: Query<Option<DepGraphFuture>>,
    parse: Query<ast::Crate>,
    crate_name: Query<String>,
    register_plugins: Query<(ast::Crate, PluginInfo)>,
    expansion: Query<(ast::Crate, Steal<Rc<RefCell<BoxedResolver>>>)>,
    dep_graph: Query<DepGraph>,
    lower_to_hir: Query<(Steal<hir::map::Forest>, ExpansionResult)>,
    prepare_outputs: Query<OutputFilenames>,
    codegen_channel: Query<(Steal<mpsc::Sender<Box<dyn Any + Send>>>,
                            Steal<mpsc::Receiver<Box<dyn Any + Send>>>)>,
    global_ctxt: Query<BoxedGlobalCtxt>,
    ongoing_codegen: Query<Box<dyn Any>>,
    link: Query<()>,
}

impl Compiler {
    pub fn dep_graph_future(&self) -> Result<&Query<Option<DepGraphFuture>>> {
        self.queries.dep_graph_future.compute(|| {
            Ok(if self.session().opts.build_dep_graph() {
                Some(rustc_incremental::load_dep_graph(self.session()))
            } else {
                None
            })
        })
    }

    pub fn parse(&self) -> Result<&Query<ast::Crate>> {
        self.queries.parse.compute(|| {
            passes::parse(self.session(), &self.input).map_err(
                |mut parse_error| {
                    parse_error.emit();
                    ErrorReported
                },
            )
        })
    }

    pub fn register_plugins(&self) -> Result<&Query<(ast::Crate, PluginInfo)>> {
        self.queries.register_plugins.compute(|| {
            let crate_name = self.crate_name()?.peek().clone();
            let krate = self.parse()?.take();

            passes::register_plugins(
                self,
                self.session(),
                self.cstore(),
                krate,
                &crate_name,
            )
        })
    }

    pub fn crate_name(&self) -> Result<&Query<String>> {
        self.queries.crate_name.compute(|| {
            let parse_result = self.parse()?;
            let krate = parse_result.peek();
            let result = match self.crate_name {
                Some(ref crate_name) => crate_name.clone(),
                None => rustc_codegen_utils::link::find_crate_name(
                    Some(self.session()),
                    &krate.attrs,
                    &self.input
                ),
            };
            Ok(result)
        })
    }

    pub fn expansion(
        &self
    ) -> Result<&Query<(ast::Crate, Steal<Rc<RefCell<BoxedResolver>>>)>> {
        self.queries.expansion.compute(|| {
            let crate_name = self.crate_name()?.peek().clone();
            let (krate, plugin_info) = self.register_plugins()?.take();
            passes::configure_and_expand(
                self.sess.clone(),
                self.cstore().clone(),
                krate,
                &crate_name,
                plugin_info,
            ).map(|(krate, resolver)| (krate, Steal::new(Rc::new(RefCell::new(resolver)))))
        })
    }

    pub fn dep_graph(&self) -> Result<&Query<DepGraph>> {
        self.queries.dep_graph.compute(|| {
            Ok(match self.dep_graph_future()?.take() {
                None => DepGraph::new_disabled(),
                Some(future) => {
                    let (prev_graph, prev_work_products) =
                        time(self.session(), "blocked while dep-graph loading finishes", || {
                            future.open().unwrap_or_else(|e| rustc_incremental::LoadResult::Error {
                                message: format!("could not decode incremental cache: {:?}", e),
                            }).open(self.session())
                        });
                    DepGraph::new(prev_graph, prev_work_products)
                }
            })
        })
    }

    pub fn lower_to_hir(&self) -> Result<&Query<(Steal<hir::map::Forest>, ExpansionResult)>> {
        self.queries.lower_to_hir.compute(|| {
            let expansion_result = self.expansion()?;
            let peeked = expansion_result.peek();
            let krate = &peeked.0;
            let resolver = peeked.1.steal();
            let hir = Steal::new(resolver.borrow_mut().access(|resolver| {
                passes::lower_to_hir(
                    self.session(),
                    self.cstore(),
                    resolver,
                    &*self.dep_graph()?.peek(),
                    &krate
                )
            })?);
            Ok((hir, BoxedResolver::to_expansion_result(resolver)))
        })
    }

    pub fn prepare_outputs(&self) -> Result<&Query<OutputFilenames>> {
        self.queries.prepare_outputs.compute(|| {
            self.lower_to_hir()?;
            let krate = self.expansion()?;
            let krate = krate.peek();
            let crate_name = self.crate_name()?;
            let crate_name = crate_name.peek();
            passes::prepare_outputs(self.session(), self, &krate.0, &*crate_name)
        })
    }

    pub fn codegen_channel(&self) -> Result<&Query<(Steal<mpsc::Sender<Box<dyn Any + Send>>>,
                                                    Steal<mpsc::Receiver<Box<dyn Any + Send>>>)>> {
        self.queries.codegen_channel.compute(|| {
            let (tx, rx) = mpsc::channel();
            Ok((Steal::new(tx), Steal::new(rx)))
        })
    }

    pub fn global_ctxt(&self) -> Result<&Query<BoxedGlobalCtxt>> {
        self.queries.global_ctxt.compute(|| {
            let crate_name = self.crate_name()?.peek().clone();
            let outputs = self.prepare_outputs()?.peek().clone();
            let hir = self.lower_to_hir()?;
            let hir = hir.peek();
            let (ref hir_forest, ref expansion) = *hir;
            let tx = self.codegen_channel()?.peek().0.steal();
            Ok(passes::create_global_ctxt(
                self,
                hir_forest.steal(),
                expansion.defs.steal(),
                expansion.resolutions.steal(),
                outputs,
                tx,
                &crate_name))
        })
    }

    pub fn ongoing_codegen(&self) -> Result<&Query<Box<dyn Any>>> {
        self.queries.ongoing_codegen.compute(|| {
            let rx = self.codegen_channel()?.peek().1.steal();
            let outputs = self.prepare_outputs()?;
            self.global_ctxt()?.peek_mut().enter(|tcx| {
                tcx.analysis(LOCAL_CRATE).ok();

                // Don't do code generation if there were any errors
                self.session().compile_status()?;

                Ok(passes::start_codegen(
                    &***self.codegen_backend(),
                    tcx,
                    rx,
                    &*outputs.peek()
                ))
            })
        })
    }

    pub fn link(&self) -> Result<&Query<()>> {
        self.queries.link.compute(|| {
            let sess = self.session();

            let ongoing_codegen = self.ongoing_codegen()?.take();

            self.codegen_backend().join_codegen_and_link(
                ongoing_codegen,
                sess,
                &*self.dep_graph()?.peek(),
                &*self.prepare_outputs()?.peek(),
            ).map_err(|_| ErrorReported)?;

            Ok(())
        })
    }

    pub fn compile(&self) -> Result<()> {
        self.prepare_outputs()?;

        if self.session().opts.output_types.contains_key(&OutputType::DepInfo)
            && self.session().opts.output_types.len() == 1
        {
            return Ok(())
        }

        self.global_ctxt()?;

        // Drop AST after creating GlobalCtxt to free memory
        mem::drop(self.expansion()?.take());

        self.ongoing_codegen()?;

        // Drop GlobalCtxt after starting codegen to free memory
        mem::drop(self.global_ctxt()?.take());

        self.link().map(|_| ())
    }
}
