/// <reference types="cypress" />
// @ts-check

const { default: axios } = require("axios")
const { MongoClient } = require("mongodb")
const fs = require("fs")
const util = require("util")

// ***********************************************************
// This example plugins/index.js can be used to load plugins
//
// You can change the location of this file or turn off loading
// the plugins file with the 'pluginsFile' configuration option.
//
// You can read more here:
// https://on.cypress.io/plugins-guide
// ***********************************************************

// This function is called when a project is opened or re-opened (e.g. due to
// the project's config changing)

function logObj(o) {
    console.log(util.inspect(o, false, null, true /* enable colors */))
}

/**
 * @type {Cypress.PluginConfig}
 */
// eslint-disable-next-line no-unused-vars
module.exports = (on, config) => {
    require("cypress-terminal-report/src/installLogsPrinter")(on, {
        printLogsToConsole: "always",
        includeSuccessfulHookLogs: true,
    })

    const registerCodeCoverageTask = require("@cypress/code-coverage/task")

    // `on` is used to hook into various events Cypress emits
    // `config` is the resolved Cypress config
    on("before:run", async (details) => {
        /*
        if (details.specs && details.browser) {
            // details.specs and details.browser will be undefined in interactive mode
            console.log(
                "Running",
                details.specs.length,
                "specs in",
                details.browser.name
            )
        }*/

        if (config.env.CI) {
            // is continous integration test run, so initialize database
            console.log("CI RUN: init database")

            const tibiDbPrefix = config.env.tibiDbPrefix
            const projectNamespace = config.env.projectApiNamespace

            // drop database from tests before
            console.log(" - connecting to mongodb: " + config.env.mongodbUri)
            const dbClient = new MongoClient(config.env.mongodbUri)
            await dbClient.connect()
            console.log(" - removing project from tibi db")
            let db = dbClient.db(tibiDbPrefix)
            db.collection("project").deleteMany({ namespace: projectNamespace })

            const dbName = tibiDbPrefix + "_" + projectNamespace
            console.log(" - dropping database: " + dbName)
            db = dbClient.db(dbName)
            await db.dropDatabase()

            // login
            const apiUrl = config.env.tibiApiUrl
            const l = await axios.post(apiUrl + "/login", {
                username: config.env.tibiUsername,
                password: config.env.tibiPassword,
            })
            const tibiToken = l.data.token

            // create project
            console.log(" - creating tibi project: " + projectNamespace)
            let project
            try {
                const p = await axios.post(
                    apiUrl + "/project",
                    {
                        configFile: config.env.projectApiConfig,
                        name: projectNamespace,
                        namespace: projectNamespace,
                        description: projectNamespace,
                    },
                    {
                        headers: {
                            "X-Auth-Token": tibiToken,
                        },
                    }
                )
                project = p.data
            } catch (e) {
                logObj(e)
                throw e
            }

            console.log(" - checking project status: " + project.id)
            try {
                const p = await axios.get(apiUrl + "/project/" + project.id, {
                    headers: {
                        "X-Auth-Token": tibiToken,
                    },
                })
                if (!p.data.api.isOnline) {
                    throw p.data
                }
            } catch (e) {
                logObj(e)
                throw e
            }

            // TODO fill tibi database with test data
        }
    })

    return registerCodeCoverageTask(on, config)
}
