#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
CodeQL for Python.
"""

import os
import shutil
import tempfile

import codeql
from .common import *

class Query(object):
    def __init__(self, path):
        """
        Arguments:
        path -- Location of the query file
        """
        # Temporaries will be cleaned up on destructor
        self.path = path

    # Helpers
    def run_command(self, command, options=[], post=[]):
        run(['query', command] + options + [self.path] + post)

    @staticmethod
    def from_source(code):
        path = temporary_file(suffix='.ql')
        with open(path, mode='w') as f:
            f.write(code)
        return Query(path)

    @staticmethod
    def from_file(path):
        return Query(path)

    # Interface
    def compile(self):
        """
        Compile or check QL code.

        Compile one or more queries. Usually the main outcome of this command is that the compiled version of the query is written
        to a compilation cache where it will be found when the query is later executed. Other output options are mostly for
        debugging.
        """
        self.run('compile')

    def run(self, database, output=None):
        """
        Run a single query.

        This command runs single query against a CodeQL database or raw QL dataset.

        By default the result of the query will be displayed on the terminal in a human-friendly rendering. If you want to do
        further processing of the results, we strongly recommend using the --output option to write the results to a file in an
        intermediate binary format, which can then be unpacked into various more machine-friendly representations by codeql
        bqrs decode.

        If your query produces results in a form that can be interpreted as source-code alerts, you may find codeql database
        analyze a more convenient way to run it. In particular, codeql database analyze can produce output in the SARIF format,
        which can be used with an variety of alert viewers.
        """
        # Return temporary results if no output is specified
        if output is None:
            output = temporary_file(suffix='.bqrs')
        # Obtain actual path to database
        if type(database) == codeql.Database:
            database = database.path
        # Perform query and return results
        options = ['-o', output, '-d', database]
        self.run_command('run', options)
        return codeql.BQRS(output)
