function nullthrows(nullable, error, onlyCheckForNull = false) {
    if (onlyCheckForNull && nullable === null) {
        throw error
    }

    if (nullable === null || nullable === undefined) {
        throw error
    }

    return nullable
}

class AutoStorageNullValueError extends Error {
    autoStorageKey = ""
    constructor(autoStorageKey) {
        const message = `Value for key ${autoStorageKey} is null`
        super(message)
        this.name = AutoStorageNullValueError.name
        this.autoStorageKey = autoStorageKey
    }
}

/**
 * abstracts parts of localStorage to make dev life great again!
 */
class AutoStorage {
    static STORAGE_TYPE = {
        MEMORY: "memory",
        SESSION: "session",
        LOCAL: "local",
    }
    /** used when we do not want to persist data in local storage. */
    unstableStorage = {}

    /** remember the object's name. used to add new items after objectn creation*/
    namespace = null

    /** used to encrypt and decrypt values writen to local storage or session storage*/
    encryptionKey = null // <---- remove

    /**
     * Used for custom handling when getting an object from AutoStorage
     * @callback validateOnGet
     * @param {any} value
     */
    /**
     * Used for custom handling when setting an object from AutoStorage
     * @callback validateOnSet
     * @param {any} value
     */

    /**
     * @typedef { ({
     * canBeEmpty: boolean,
     * storageType: "memory"|"session"|"local",
     * defaultValue: *,
     * }|undefined)} Settings
     */

    /** @type Settings */
    settings = {}

    /**
     * a object that stores the name of the getter/setter to then act upon it. 
     * example: `BookStorage.bookSettings.actOn.deploymentId.updateStorageType("local")`
     * will update the storage type to "local" for the attribute `deploymentId`.  
     */
    actOn = {}

    /**
     * @param {string} namespace the name of the storage object. This is used to keep track of 
     * attributes with the same name but in different AutoStorage objects.
     * @param {{[string]: {
     *  settings: Settings, 
     *  validateOnGet: validateOnGet,
     *  validateOnSet: validateOnSet,
     * }}} obj an array of tuples, where the first 
     * value is the name of getter / setter of the attribute, and the second value is a settings 
     * object which can be undefined if the attribute using the default settings.
     */
    constructor(namespace, obj) {
        const settingsForTheClassSettings = { storageType: AutoStorage.STORAGE_TYPE.LOCAL, encrypt: false, localOnly: true }
        const settingsKey = `${namespace}.__AutoStorage_Settings__` // lets make this a function

        this.namespace = namespace
        for (const [name, params] of Object.entries(obj)) {
            this.#initializeItem(namespace, name, params, settingsForTheClassSettings, settingsKey)
        }
        // persist the settings object in local sotrage
        this.setItem(settingsKey, JSON.stringify(this.settings), settingsForTheClassSettings)
    }

    /**
     * Private. Sets up one key-value pair.
     * @param {string} namespace 
     * @param {string} name 
     * @param {object} params  
     * @param {string} settingsForTheClassSettings  
     * @param {string} params  
     */
    #initializeItem(namespace, name, params, settingsForTheClassSettings, settingsKey) {
        //console.log("at initializeItem",namespace, name, params,settingsForTheClassSettings,settingsKey)
        const savedSettings = this.getItem(settingsKey, settingsForTheClassSettings, undefined, true) || {}
        this.settings[name] = savedSettings[name] || params.settings || {}
        const key = `${namespace}.${name}`

        if (this[name]) { throw new CannotInitializeItemThatAlreadyExsists(name) }

        // creating the getter/setter
        this[name] = (value) => {
            if (value === undefined) {
                // getting the value stored for this `name`
                try {
                    const value = this.getItem(key, this.settings[name], params.validateOnGet)
                    return value
                } catch (error) {
                    if (error instanceof AutoStorageNullValueError) {
                        if (this.settings[name]?.canBeEmpty) {
                            return null
                        }
                    }
                    throw error
                }
            } else {
                // setting the value stored for this name
                return this.setItem(key, JSON.stringify(value), this.settings[name], params.validateOnSet)
            }
        }

        this.actOn[name] = {
            updateStorageType: (storageTypeString) => {

                // get the value BEFORE we remove it (and it's key)
                try {
                    //console.log("name", name)
                    const valueFromOldStorageSystem = this[name]()
                    this.removeItem(key, this.settings[name])
                    this.settings[name].storageType = storageTypeString
                    this[name](valueFromOldStorageSystem)
                } catch (error) {
                    if (!(error instanceof AutoStorageNullValueError)) {
                        throw error
                    }
                } finally {
                    this.settings[name].storageType = storageTypeString
                    // now we change the storage type to what we want. Then 
                    // we call the setter as normal
                    this.setItem(settingsKey, JSON.stringify(this.settings), settingsForTheClassSettings)
                }


            },
            delete: () => this.removeItem(key, this.settings[name]),
        }

        if (this.settings[name]?.defaultValue !== undefined) {
            try {
                this.getItem(key, this.settings[name], params.validateOnGet) // if this throws then we need to put in the default value
            } catch (error) {
                if (error instanceof AutoStorageNullValueError) {
                    this[name](this.settings[name]?.defaultValue) // putting in the default value
                } else {
                    throw error
                }
            }
        }
    }

    /**
    * deletes all variables, initializes those with default values
    *
    */
    reset() { // <---- remove
        //console.log("at reset", this.settings)
        for (const key of Object.keys(this.actOn)) {
            if (this.settings[key].defaultValue !== undefined) {
                //debugger
                this.setItem(this.namespace + "." + key, JSON.stringify(this.settings[key].defaultValue), this.settings[key])
            } else {
                this.actOn[key].delete()
            }
            //console.log(key, this.actOn[key])
            //this.actOn[key].updateStorageType(storageType)
        }
    }

    /**
     * Private. Gets the the given key-value.
     * @param {string} key 
     * @param {Settings} settings 
     * @param {validateOnGet} validateOnGet  
     * @param {boolean} doNotThrowIfNull only for internal use 
     * @returns 
     */
    getItem(key, settings, validateOnGet = undefined, doNotThrowIfNull = false) {
        const item = this.getItemFromStorage(key, settings)
        return this.validateItem(item, key, settings, validateOnGet, doNotThrowIfNull)
    }

    getItemFromStorage(key, settings) {
        let item
        switch (settings?.storageType) {
            case AutoStorage.STORAGE_TYPE.MEMORY:
                item = this.unstableStorage[key]
                break
            case AutoStorage.STORAGE_TYPE.SESSION:
                item = sessionStorage.getItem(key)
                break
            default:
                item = localStorage.getItem(key)
                break
        }
        return item
    }

    validateItem(item, key, settings, validateOnGet = undefined, doNotThrowIfNull = false) {
        if (typeof validateOnGet === 'function') {
            // we can let the developer decide how to handle getting an item
            item = JSON.parse(item)
            validateOnGet(item)
            return item
        } else if (doNotThrowIfNull) {
            // this is only when we explicity do not care what the value is
            try {
                return JSON.parse(item)
            } catch (e) {
                //console.log("returning default value")
                return settings.defaultValue
            }
        } else {
            // otherwise, use the default validation
            const raw_value = nullthrows(item, new AutoStorageNullValueError(key))
            // now try to parse the value, if it fails, the token has not decrypted the value correctly.
            try {
                return JSON.parse(raw_value)
            } catch (e) {
                //console.log("--returning default")
                return settings.defaultValue
            }

        }
    }

    /**
     * Private. Sets the the given key-value.
     * @param {string} key 
     * @param {string} rawValue json string of value
     * @param {Settings} settings 
     * @param {validateOnSet} validateOnSet 
     */
    setItem(key, value, settings, validateOnSet) {
        if (typeof validateOnSet === "function") {
            validateOnSet(value)
        }
        switch (settings?.storageType) {
            case AutoStorage.STORAGE_TYPE.MEMORY:
                this.unstableStorage[key] = value
                break
            case AutoStorage.STORAGE_TYPE.SESSION:
                sessionStorage.setItem(key, value)
                break
            default:
                localStorage.setItem(key, value)
                break
        }
        return value
    }

    /**
     * Removes the given key-value.
     * @param {string} key 
     * @param {Settings} settings 
     * @returns 
     */
    removeItem(key, settings) {
        switch (settings?.storageType) {
            case AutoStorage.STORAGE_TYPE.MEMORY:
                delete this.unstableStorage[key]
                return
            case AutoStorage.STORAGE_TYPE.SESSION:
                return sessionStorage.removeItem(key)
            default:
                return localStorage.removeItem(key)
        }
    }
    /**
     * Report if a key exists.
     * @param {string} name 
     * @returns
     */
    exists(name) {
        return this[name] !== undefined
    }
    /**
     * adds a new key-value.
     * @param {string} name 
     * @param {object} params  
     */
    addItem(name, params = { settings: {} }) {
        const settingsForTheClassSettings = { storageType: AutoStorage.STORAGE_TYPE.LOCAL, encrypt: false, localOnly: true }
        const settingsKey = `${this.namespace}.__AutoStorage_Settings__`
        //console.log(name, params)
        const new_params = JSON.parse(JSON.stringify(params))
        if (!new_params.settings.storageType) {
            if (this.isPrivateComputer()) {
                new_params.settings.storageType = AutoStorage.STORAGE_TYPE.LOCAL
            } else {
                new_params.settings.storageType = AutoStorage.STORAGE_TYPE.SESSION
            }
        }
        //console.log("new params", new_params)
        this.#initializeItem(this.namespace, name, new_params, settingsForTheClassSettings, settingsKey)

        // persist the settings object in local sotrage
        this.setItem(settingsKey, JSON.stringify(this.settings), settingsForTheClassSettings)

    }

    updateStorageType(storageType) {
        //moves all items to the specified storage time (e.g. local or session)
        debug()
        for (const key of Object.keys(this.actOn)) {
            this.actOn[key].updateStorageType(storageType)
        }
    }

    getKeys() {
        //returns the set of keys in the namespace
        const keys = []
        for (const key of Object.keys(this.actOn)) {
            keys.push(key)
        }
        return keys
    }
}

class SecretStorage extends AutoStorage {
    constructor(namespace, obj, encryptionKey) {
        super(namespace, obj)
        this.encryptionKey = JSON.parse(sessionStorage.getItem(namespace + ".token")) || JSON.parse(localStorage.getItem(namespace + ".token")) // <---- remove

        //console.log("setting encrytion key in constructopr", encryptionKey)

        if (this.encryptionKey === 'null' || this.encryptionKey === null) { // <---- remove
            // no token, this is a new login, use the default token
            this.encryptionKey = ncrypt("Shall we sin on still impenitent and incorrigible?", encryptionKey)
        }
    }

    /**
     * reports if the current submitted encryption key is able to decrypt values in the namespace.
     * @param {string} encryptionKey 
     * @returns 
     */
    authenticate() {
        return (dcrypt(this.canary(), this.token()) === "logged in")
    }
    /**
     * reports if the current encryption key is able to decrypt values in the namespace.
     * @returns 
     */
    loggedIn() {
        return (this.authenticate())
    }
    /**
     * reports if the current password sent is is able to decrypt the canary.
     * @returns 
     */
    login(password) {
        const temp_token = ncrypt("Shall we sin on still impenitent and incorrigible?", password)
        if (dcrypt(this.canary(), temp_token) === "logged in") {
            this.token(temp_token)
            return true
        }
        return false
    }

    /**
    * Logs the user out by deleting the token.
    */
    logout() {
        localStorage.removeItem(this.namespace + ".token")
        localStorage.removeItem(this.namespace + ".gasToken")
        // clear anything that is session storage
        for (const [key, settings] of Object.entries(this.settings)) {
            if (settings.storageType === AutoStorage.STORAGE_TYPE.SESSION) {
                this.removeItem(this.namespace + "." + key, settings)
            }
        }
        window.location.reload()
    }

    changeEncryptionKey(new_encryption_key) {
        //updates the encryption key and transcodes all stored values
        const plain_text_values = {}
        for (const key of Object.keys(this.actOn)) {
            let value = null
            try {
                value = this[key]()
            } catch (e) {
                // throws if null, which is fine is this context
            }

            if (value !== null) {
                //console.log(this.settings[key], key, value)
                plain_text_values[key] = value
            }
        }

        this.encryptionKey = ncrypt("Shall we sin on still impenitent and incorrigible?", new_encryption_key)
        for (const [key, val] of Object.entries(plain_text_values)) {
            //console.log("-->",key, val, this.settings[key], this.encryptionKey)
            if (key !== "token") {
                this[key](val)
            }
        }

        this.token(this.encryptionKey)
        this.canary(ncrypt("logged in", this.encryptionKey))
    }

    getItemFromStorage(key, settings) {
        const item = super.getItemFromStorage(key, settings)
        if (settings.encrypt !== false) { // explict check against false, that means unless it is set to false we plan to encrypt or decrypt
            return dcrypt(item, this.encryptionKey + key)
        }
        return item
    }

    setItem(key, rawValue, settings, validateOnSet) {

        if (rawValue === this.getItemFromStorage(key, settings)) {
            // the property already has this value
            return false
        }

        const value = (
            settings.encrypt === false
                ? rawValue
                : ncrypt(rawValue, this.encryptionKey + key)
        )

        const returnValue = super.setItem(key, value, settings, validateOnSet) // calls the autoStorage method 
        // if the token was updated, we need to update the encryption key
        if (key === this.namespace + ".token") {
            this.encryptionKey = JSON.parse(rawValue)
        }

        return true
    }
}

class SuperStorage extends SecretStorage {


    constructor(namespace, obj, encryptionKey) {
        super(namespace, obj, encryptionKey)
        this.batch = {}
        this.timeoutId = null
    }

    getGasToken() {
        let gas_token
        try {
            gas_token = this.gasToken()
        } catch (e) {
            gas_token = null
        }
        return gas_token
    }

    setItem(key, rawValue, settings, validateOnSet) {
        // synchonusly write to the local storage
        const did_set = super.setItem(key, rawValue, settings, validateOnSet)
        // we have written to local storage, now write to server if configured

        if (!settings.localOnly && did_set) {
            this.debouncedServerPost({ id: key.split(".")[1], value: rawValue })
        }

        return this
    }

    debouncedServerPost(data){
        if(this.batch!==undefined){
            // Gove and Eli are not sure why this.batch is undefined when it is starting up
            // however, without this if statement, the page breaks when first loaded
            this.batch[data.id] = data
            this.internalDebounce(Object.values(this.batch))
        }
    }

    internalDebounce = debounce(async (batch) => {
        // this function will only be called 1 second after not being called. 
        const json_data = await server_post({
            "mode": "property",
            "token": this.getGasToken(),
            "action": "set",
            "key": "book_storage",
            "dataArray": batch,
        })
        this.batch = {}
        if (json_data?.status === "success") {
            return json_data
        } else {
            throw json_data
        }

    }, 1000)
}


const BookStorage = new SuperStorage("BookStorage", {
    aiType: { settings: { defaultValue: 'noai', storageType: AutoStorage.STORAGE_TYPE.SESSION } },
    dbType: { settings: { defaultValue: 'sqlite', storageType: AutoStorage.STORAGE_TYPE.SESSION } },
    loginType: { settings: { defaultValue: 'none', encrypt: false, storageType: AutoStorage.STORAGE_TYPE.SESSION, localOnly: true } },
    canary: { settings: { defaultValue: 'k7brL/5r8xfk9Beh+35EDW4=', encrypt: false, storageType: AutoStorage.STORAGE_TYPE.SESSION, localOnly: true } },
    token: { settings: { defaultValue: 'rd2vWW1cG6tOpcVpqurU8vR/m33ZRHbXA0ZAE9k2DbLv8msunrrLWs25R4ejAc6Ur4Kb/hRqQ/K2mA==', encrypt: false, storageType: AutoStorage.STORAGE_TYPE.SESSION, localOnly: true } },
    currentPage: { settings: { storageType: AutoStorage.STORAGE_TYPE.SESSION, localOnly: true } },
    studentFirstName: { settings: { storageType: AutoStorage.STORAGE_TYPE.SESSION } },
    studentLastName: { settings: { storageType: AutoStorage.STORAGE_TYPE.SESSION } },
    studentId: { settings: { storageType: AutoStorage.STORAGE_TYPE.SESSION } },
    studentEmail: { settings: { storageType: AutoStorage.STORAGE_TYPE.SESSION } },
    courseCode: { settings: { storageType: AutoStorage.STORAGE_TYPE.SESSION } },
    paidUsername: { settings: { storageType: AutoStorage.STORAGE_TYPE.SESSION } },
    deploymentId: { settings: { storageType: AutoStorage.STORAGE_TYPE.SESSION, localOnly: true } },
    localCanary: { settings: { storageType: AutoStorage.STORAGE_TYPE.SESSION, localOnly: true } },
    gasToken: { settings: { storageType: AutoStorage.STORAGE_TYPE.SESSION, localOnly: true } },
    dwToken: { settings: { storageType: AutoStorage.STORAGE_TYPE.SESSION } },
    oracleURL: { settings: { storageType: AutoStorage.STORAGE_TYPE.SESSION } },
    queryEditor: { settings: { storageType: AutoStorage.STORAGE_TYPE.SESSION } },
    tutorials: { settings: { storageType: AutoStorage.STORAGE_TYPE.SESSION } },
    isPrivateComputer: {
        settings: {
            storageType: AutoStorage.STORAGE_TYPE.SESSION,
            defaultValue: false,
            encrypt: false,
            localOnly: true
        },
    }
}, "Samuel Davies")
