#  File src/library/base/baseloader.R
#  Part of the R package, https://www.R-project.org
#
#  Copyright (C) 1995-2020 The R Core Team
#
#  This program is free software; you can redistribute it and/or modify
#  it under the terms of the GNU General Public License as published by
#  the Free Software Foundation; either version 2 of the License, or
#  (at your option) any later version.
#
#  This program is distributed in the hope that it will be useful,
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#  GNU General Public License for more details.
#
#  A copy of the GNU General Public License is available at
#  https://www.R-project.org/Licenses/


## should be kept in step with code in  >> R/lazyload.R <<
## (but not everywhere ?!)
.Internal(eval(quote({
..lazyLoad <- function(filebase, envir = parent.frame())
{
    ##
    ## bootstrapping definitions so we can load base
    ##
    glue <- function (..., sep = " ", collapse = NULL)
##      .Internal(paste(list(...), sep, collapse, TRUE))# recycle0=TRUE
        .Internal(paste(list(...), sep, collapse, FALSE))
    readRDS <- function (file) {
        halt <- function (message) .Internal(stop(TRUE, message))
        gzfile <- function (description, open)
            .Internal(gzfile(description, open, "", 6))
        close <- function (con) .Internal(close(con, "rw"))
        if (! is.character(file)) halt("bad file name")
        con <- gzfile(file, "rb")
        on.exit(close(con))
        .Internal(unserializeFromConn(con, baseenv()))
    }
    `parent.env<-` <-
        function (env, value) .Internal(`parent.env<-`(env, value))
    existsInFrame <- function (x, env) .Internal(exists(x, env, "any", FALSE))
    list2env <- function (x, envir) .Internal(list2env(x, envir))
    environment <- function () .Internal(environment(NULL))
    mkenv <- function() .Internal(new.env(TRUE, baseenv(), 29L))

    ##
    ## main body
    ##
    mapfile  <- glue(filebase, "rdx", sep = ".")
    datafile <- glue(filebase, "rdb", sep = ".")
    env <- mkenv()
    map <- readRDS(mapfile)
    vars <- names(map$variables)
    compressed <- map$compressed
    list2env(map$references, env)
    envenv <- mkenv()
    envhook <- function(n) {
        if (existsInFrame(n, envenv))
            envenv[[n]]
        else {
            e <- mkenv()
            envenv[[n]] <- e           # MUST do this immediately
            key <- env[[n]]
            data <- lazyLoadDBfetch(key, datafile, compressed, envhook)
            parent.env(e) <- if(!is.null(data$enclos)) data$enclos else emptyenv()
            list2env(data$bindings, e)
            if (! is.null(data$attributes))
                attributes(e) <- data$attributes
            ## there are no S4 objects in base
            if (! is.null(data$locked) && data$locked)
                .Internal(lockEnvironment(e, FALSE))
            e
        }
    }
    expr <- quote(lazyLoadDBfetch(key, datafile, compressed, envhook))
    this <- environment()
    .Internal(makeLazy(vars, map$variables, expr, this, envir))

    ## reduce memory use
    map <- NULL
    vars <- NULL
    vals <- NULL
    rvars <- NULL
    mapfile <- NULL
    readRDS <- NULL
}

    existsInBase <- function (x)
        .Internal(exists(x, .BaseNamespaceEnv, "any", TRUE))
    glue <- function(..., sep = " ")
        .Internal(paste(list(...), sep, collapse=NULL, FALSE))

    basedb <- glue(.Internal(R.home()), "library", "base", "R",
                   "base", sep= .Platform$file.sep)

    ..lazyLoad(basedb, baseenv())

}), .Internal(new.env(FALSE, baseenv(), 29L)), baseenv()))

## keep in sync with R/zzz.R
as.numeric <- as.double
is.name <- is.symbol


## populate C/Fortran symbols
local({
    routines <- getDLLRegisteredRoutines("base")
    for (i in c("dchdc", # chol, deprecated
                "dqrcf", "dqrdc2", "dqrqty", "dqrqy", "dqrrsd", "dqrxb", # qr
                "dtrco")) # .kappa_tri
        assign(paste0(".F_", i), routines[[3]][[i]], envir = .BaseNamespaceEnv)
    for(i in 1:2)
        lapply(routines[[i]],
               function(sym) assign(paste0(".C_", sym$name), sym, envir = .BaseNamespaceEnv))
})

## make sure these two promises are forced to avoid recursive invocation
## of "args" and consequent "promise already under evaluation" error

invisible(force(.ArgsEnv))
invisible(force(.GenericArgsEnv))

## also force these condition system callback promises to avoid
## recursive invocation in some rare situations at start-up
invisible(force(.signalSimpleWarning))
invisible(force(.handleSimpleError))
invisible(force(.tryResumeInterrupt))

local({
    assignWrapped <- function(x, method, home, envir) {
        method <- method                # force evaluation
        home <- home                    # force evaluation
        delayedAssign(x, get(method, envir = home), assign.env = envir)
    }
    methods <- paste0(.S3_methods_table[, 1L], ".",
                      .S3_methods_table[, 2L])
    env <- .BaseNamespaceEnv
    table <- env[[".__S3MethodsTable__."]]
    for(m in methods)
        assignWrapped(m, m, env, table)
})
