<commit_before>/*
 * Copyright (C) 2020 <NAME>
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package uk.co.reecedunn.intellij.plugin.marklogic.query.rest.debugger

import com.google.gson.JsonObject
import com.intellij.lang.Language
import com.intellij.openapi.vfs.VirtualFile
import org.apache.http.client.methods.HttpUriRequest
import org.apache.http.client.methods.RequestBuilder
import org.apache.http.util.EntityUtils
import uk.co.reecedunn.intellij.plugin.core.http.mime.MimeResponse
import uk.co.reecedunn.intellij.plugin.core.lang.getLanguageMimeTypes
import uk.co.reecedunn.intellij.plugin.core.vfs.decode
import uk.co.reecedunn.intellij.plugin.intellij.lang.XPathSubset
import uk.co.reecedunn.intellij.plugin.marklogic.query.rest.BuildableQuery
import uk.co.reecedunn.intellij.plugin.marklogic.query.rest.queryResults
import uk.co.reecedunn.intellij.plugin.processor.database.DatabaseModule
import uk.co.reecedunn.intellij.plugin.processor.debug.DebugSession
import uk.co.reecedunn.intellij.plugin.processor.debug.DebuggableQuery
import uk.co.reecedunn.intellij.plugin.processor.query.*
import uk.co.reecedunn.intellij.plugin.processor.query.http.HttpConnection
import uk.co.reecedunn.intellij.plugin.xdm.types.impl.values.toXsDuration

internal class MarkLogicDebugQuery(
    private val builder: RequestBuilder,
    private val queryParams: JsonObject,
    private val queryFile: VirtualFile,
    private val connection: HttpConnection
) : DebuggableQuery, BuildableQuery {
    // region Query

    private var variables: JsonObject = JsonObject()
    private var types: JsonObject = JsonObject()

    override var rdfOutputFormat: Language? = null

    override var updating: Boolean = false

    override var xpathSubset: XPathSubset = XPathSubset.XPath

    override var server: String = ""

    override var database: String = ""

    override var modulePath: String = ""

    private var contextValue: String = ""
    private var contextPath: String = ""

    override fun bindVariable(name: String, value: Any?, type: String?) {
        variables.addProperty(name, value as String? ?: "")
        types.addProperty(name, type)
    }

    override fun bindContextItem(value: Any?, type: String?) {
        // NOTE: Only supported for XSLT files.
        when (value) {
            is DatabaseModule -> contextPath = value.path
            is VirtualFile -> contextValue = value.decode()!!
            else -> contextValue = value.toString()
        }
    }

    // endregion
    // region BuildableQuery

    override fun request(): HttpUriRequest {
        val params = queryParams.deepCopy()
        params.addProperty("vars", variables.toString())
        params.addProperty("types", types.toString())
        params.addProperty("rdf-output-format", rdfOutputFormat?.getLanguageMimeTypes()?.get(0) ?: "")
        params.addProperty("updating", updating.toString())
        params.addProperty("server", server)
        params.addProperty("database", database)
        params.addProperty("module-root", modulePath)
        params.addProperty("context-value", contextValue)
        params.addProperty("context-path", contextPath)

        builder.addParameter("vars", params.toString())
        builder.charset = Charsets.UTF_8
        return builder.build()
    }

    // endregion
    // region RunnableQuery

    override fun run(): QueryResults {
        val response = connection.execute(request())
        val body = EntityUtils.toString(response.entity)
        response.close()

        val results = MimeResponse(response.allHeaders, body, Charsets.UTF_8).queryResults(queryFile).iterator()
        val duration = (results.next().value as String).toXsDuration()
        return QueryResults(response.statusLine, results.asSequence().toList(), duration!!)
    }

    // endregion
    // region DebuggableQuery

    override val session: DebugSession = MarkLogicDebugSession()

    // endregion
    // region Closeable

    override fun close() {
    }

    // endregion
}<commit_msg>[MarkLogic] Debug queries don't return a run duration.<commit_after>/*
 * Copyright (C) 2020 <NAME>
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package uk.co.reecedunn.intellij.plugin.marklogic.query.rest.debugger

import com.google.gson.JsonObject
import com.intellij.lang.Language
import com.intellij.openapi.vfs.VirtualFile
import org.apache.http.client.methods.HttpUriRequest
import org.apache.http.client.methods.RequestBuilder
import org.apache.http.util.EntityUtils
import uk.co.reecedunn.intellij.plugin.core.http.mime.MimeResponse
import uk.co.reecedunn.intellij.plugin.core.lang.getLanguageMimeTypes
import uk.co.reecedunn.intellij.plugin.core.vfs.decode
import uk.co.reecedunn.intellij.plugin.intellij.lang.XPathSubset
import uk.co.reecedunn.intellij.plugin.marklogic.query.rest.BuildableQuery
import uk.co.reecedunn.intellij.plugin.marklogic.query.rest.queryResults
import uk.co.reecedunn.intellij.plugin.processor.database.DatabaseModule
import uk.co.reecedunn.intellij.plugin.processor.debug.DebugSession
import uk.co.reecedunn.intellij.plugin.processor.debug.DebuggableQuery
import uk.co.reecedunn.intellij.plugin.processor.query.*
import uk.co.reecedunn.intellij.plugin.processor.query.http.HttpConnection
import uk.co.reecedunn.intellij.plugin.xdm.types.XsDurationValue
import uk.co.reecedunn.intellij.plugin.xdm.types.impl.values.XsDuration
import uk.co.reecedunn.intellij.plugin.xdm.types.impl.values.toXsDuration

internal class MarkLogicDebugQuery(
    private val builder: RequestBuilder,
    private val queryParams: JsonObject,
    private val queryFile: VirtualFile,
    private val connection: HttpConnection
) : DebuggableQuery, BuildableQuery {
    // region Query

    private var variables: JsonObject = JsonObject()
    private var types: JsonObject = JsonObject()

    override var rdfOutputFormat: Language? = null

    override var updating: Boolean = false

    override var xpathSubset: XPathSubset = XPathSubset.XPath

    override var server: String = ""

    override var database: String = ""

    override var modulePath: String = ""

    private var contextValue: String = ""
    private var contextPath: String = ""

    override fun bindVariable(name: String, value: Any?, type: String?) {
        variables.addProperty(name, value as String? ?: "")
        types.addProperty(name, type)
    }

    override fun bindContextItem(value: Any?, type: String?) {
        // NOTE: Only supported for XSLT files.
        when (value) {
            is DatabaseModule -> contextPath = value.path
            is VirtualFile -> contextValue = value.decode()!!
            else -> contextValue = value.toString()
        }
    }

    // endregion
    // region BuildableQuery

    override fun request(): HttpUriRequest {
        val params = queryParams.deepCopy()
        params.addProperty("vars", variables.toString())
        params.addProperty("types", types.toString())
        params.addProperty("rdf-output-format", rdfOutputFormat?.getLanguageMimeTypes()?.get(0) ?: "")
        params.addProperty("updating", updating.toString())
        params.addProperty("server", server)
        params.addProperty("database", database)
        params.addProperty("module-root", modulePath)
        params.addProperty("context-value", contextValue)
        params.addProperty("context-path", contextPath)

        builder.addParameter("vars", params.toString())
        builder.charset = Charsets.UTF_8
        return builder.build()
    }

    // endregion
    // region RunnableQuery

    override fun run(): QueryResults {
        val response = connection.execute(request())
        val body = EntityUtils.toString(response.entity)
        response.close()

        val results = MimeResponse(response.allHeaders, body, Charsets.UTF_8).queryResults(queryFile).iterator()
        return QueryResults(response.statusLine, results.asSequence().toList(), XsDuration.ZERO)
    }

    // endregion
    // region DebuggableQuery

    override val session: DebugSession = MarkLogicDebugSession()

    // endregion
    // region Closeable

    override fun close() {
    }

    // endregion
}
{'fraction_non_alphanumeric': 0.10286401399212942, 'fraction_numerical': 0.002404897245299519, 'mean_word_length': 3.595178302360623, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3409158', 'n_tokens_mistral': 2601, 'n_tokens_neox': 2538, 'n_words': 616}