import requests


def dataset_definition(connection, dataset_id, fields=None, verbose=False):
    """Get the definition of a dataset.

    Args:
        connection (object): MicroStrategy connection object returned by `microstrategy.Connection()`.
        dataset_id (str): Identifier of a pre-existing dataset. Used when updating a pre-existing dataset.
        fields(list, optional): Specifies object types to be returned. Possible values include tables, columns,
            attributes, and metrics. If no value is set, attributes and metrics are returned.
        verbose (bool, optional): Verbosity of server responses; defaults to False.

    Returns:
        HTTP response object returned by the MicroStrategy REST server

    """
    response = requests.get(url=connection.base_url + '/datasets/' + dataset_id,
                            headers={'X-MSTR-AuthToken': connection.auth_token,
                                     'X-MSTR-ProjectID': connection.project_id},
                            params={'fields': fields},
                            cookies=connection.cookies,
                            verify=connection.ssl_verify)
    if verbose:
        print(response.url)
    return response


def create_dataset(connection, body, verbose=False):
    """Create a single-table dataset from external data uploaded to the MicroStrategy Intelligence Server.

    Args:
        connection (object): MicroStrategy connection object returned by `microstrategy.Connection()`.
        body (str): JSON-formatted definition of the dataset. Generated by `utils.formjson()`.
        verbose (bool, optional): Verbosity of server responses; defaults to False.

    Returns:
        HTTP response object returned by the MicroStrategy REST server

    """
    response = requests.post(url=connection.base_url + '/datasets',
                             headers={'X-MSTR-AuthToken': connection.auth_token,
                                      'X-MSTR-ProjectID': connection.project_id},
                             cookies=connection.cookies,
                             json=body,
                             verify=connection.ssl_verify)

    if verbose:
        print(response.url)
    return response


def update_dataset(connection, dataset_id, table_name, update_policy, body, verbose=False, table_id=None):
    """Update a single-table dataset with external data uploaded to the MicroStrategy Intelligence Server.

    Args:
        connection (object): MicroStrategy connection object returned by `microstrategy.Connection()`.
        dataset_id (str): Identifier of a pre-existing dataset. Used when updating a pre-existing dataset.
        table_id (str): Identifier of the table to update within the MicroStrategy dataset.
        update_policy (str):  Update operation type: 'Add' (inserts new, unique rows), 'Update' (updates data in
            existing rows and columns), 'Upsert' (updates existing data and inserts new rows), 'Replace' (similar to
            truncate, replaces the existing data with new data).
        body (str): JSON-formatted definition of the dataset. Generated by `utils.formjson()`.
        verbose (bool, optional): Verbosity of server responses; defaults to False.

    Returns:
        HTTP response object returned by the MicroStrategy REST server

    """
    response = requests.patch(url=connection.base_url + '/datasets/' + dataset_id + '/tables/' + table_name,
                              headers={'X-MSTR-AuthToken': connection.auth_token,
                                       'X-MSTR-ProjectID': connection.project_id,
                                       'updatePolicy': update_policy},
                              cookies=connection.cookies,
                              json=body,
                              verify=connection.ssl_verify)
    if verbose:
        print(response.url)
    return response


def delete_dataset(connection, dataset_id, verbose=False):
    """Delete a dataset previously created using the REST API.

    Args:
        connection (object): MicroStrategy connection object returned by `microstrategy.Connection()`.
        dataset_id (str): Identifier of a pre-existing dataset. Used when updating a pre-existing dataset.
        verbose (bool, optional): Verbosity of server responses; defaults to False.

    Returns:
        HTTP response object returned by the MicroStrategy REST server

    """
    response = requests.delete(url=connection.base_url + '/objects/' + dataset_id + '?type=3',
                               headers={'X-MSTR-AuthToken': connection.auth_token,
                                        'X-MSTR-ProjectID': connection.project_id},
                               cookies=connection.cookies, verify=connection.ssl_verify)

    if verbose:
        print(response.url)
    return response


def create_multitable_dataset(connection, body, verbose=False):
    """Create the definition of a multi-table dataset.

    Args:
        connection (object): MicroStrategy connection object returned by `microstrategy.Connection()`.
        body (dict): JSON-formatted payload containing the body of the request.
        verbose (bool, optional): Verbosity of server responses; defaults to False.

    Returns:
        HTTP response object returned by the MicroStrategy REST server

    """
    response = requests.post(url=connection.base_url + '/datasets/models',
                             headers={'X-MSTR-AuthToken': connection.auth_token,
                                      'X-MSTR-ProjectID': connection.project_id},
                             cookies=connection.cookies,
                             json=body,
                             verify=connection.ssl_verify)

    if verbose:
        print(response.url)
    return response


def upload_session(connection, dataset_id, body, verbose=False):
    """Create a multi-table dataset upload session.

    Args:
        connection (object): MicroStrategy connection object returned by `microstrategy.Connection()`.
        dataset_id (str): Identifier of a pre-existing dataset. Used when updating a pre-existing dataset.
        body (dict): JSON-formatted payload containing the body of the request.
        verbose (bool, optional): Verbosity of server responses; defaults to False.

    Returns:
        HTTP response object returned by the MicroStrategy REST server

    """

    response = requests.post(url=connection.base_url + '/datasets/' + dataset_id + '/uploadSessions',
                             headers={'X-MSTR-AuthToken': connection.auth_token,
                                      'X-MSTR-ProjectID': connection.project_id},
                             cookies=connection.cookies,
                             json=body,
                             verify=connection.ssl_verify)
    if verbose:
        print(response.url)
    return response


def upload(connection, dataset_id, session_id, body, verbose=False):
    """Upload data to a multi-table dataset.

    Args:
        connection (object): MicroStrategy connection object returned by `microstrategy.Connection()`.
        dataset_id (str): Identifier of a pre-existing dataset. Used when updating a pre-existing dataset.
        session_id (str): Identifer of the server session used for collecting uploaded data.
        body (dict): JSON-formatted payload containing the body of the request.
        verbose (bool, optional): Verbosity of server responses; defaults to False.

    Returns:
        HTTP response object returned by the MicroStrategy REST server

    """

    response = requests.put(url=connection.base_url + '/datasets/' + dataset_id + '/uploadSessions/' + session_id,
                            headers={'X-MSTR-AuthToken': connection.auth_token,
                                     'X-MSTR-ProjectID': connection.project_id},
                            cookies=connection.cookies,
                            json=body,
                            verify=connection.ssl_verify)
    if verbose:
        print(response.url)
    return response


def publish(connection, dataset_id, session_id, verbose=False):
    """Publish a multi-table dataset.

    Args:
        connection (object): MicroStrategy connection object returned by `microstrategy.Connection()`.
        dataset_id (str): Identifier of a pre-existing dataset. Used when updating a pre-existing dataset.
        session_id (str): Identifer for the server session used for collecting uploaded data.
        verbose (bool, optional): Verbosity of server responses; defaults to False.

    Returns:
        HTTP response object returned by the MicroStrategy REST server

    """

    response = requests.post(url=connection.base_url + '/datasets/' + dataset_id + '/uploadSessions/' + session_id + '/publish',
                             headers={'X-MSTR-AuthToken': connection.auth_token,
                                      'X-MSTR-ProjectID': connection.project_id},
                             cookies=connection.cookies,
                             verify=connection.ssl_verify)
    if verbose:
        print(response.url)
    return response


def publish_status(connection, dataset_id, session_id, verbose=False):
    """Get multi-table dataset publication status.

    Args:
        connection (object): MicroStrategy connection object returned by `microstrategy.Connection()`.
        dataset_id (str): Identifier of a pre-existing dataset. Used when updating a pre-existing dataset.
        session_id (str): Identifer for the server session used for collecting uploaded data.
        verbose (bool, optional): Verbosity of server responses; defaults to False.

    Returns:
        HTTP response object returned by the MicroStrategy REST server

    """

    response = requests.get(url=connection.base_url + '/datasets/' + dataset_id + '/uploadSessions/' + session_id + '/publishStatus',
                            headers={'X-MSTR-AuthToken': connection.auth_token,
                                     'X-MSTR-ProjectID': connection.project_id},
                            cookies=connection.cookies,
                            verify=connection.ssl_verify)
    if verbose:
        print(response.url)
    return response


def publish_cancel(connection, dataset_id, session_id, verbose=False):
    """Delete a multi-table dataset upload session and cancel publication.

    Args:
        connection (object): MicroStrategy connection object returned by `microstrategy.Connection()`.
        dataset_id (str): Identifier of a pre-existing dataset. Used when updating a pre-existing dataset.
        session_id (str): Identifer for the server session used for collecting uploaded data.
        verbose (bool, optional): Verbosity of server responses; defaults to False.

    Returns:
        HTTP response object returned by the MicroStrategy REST server

    """

    response = requests.delete(url=connection.base_url + '/datasets/' + dataset_id + '/uploadSessions/' + session_id,
                               headers={'X-MSTR-AuthToken': connection.auth_token,
                                        'X-MSTR-ProjectID': connection.project_id},
                               cookies=connection.cookies,
                               verify=connection.ssl_verify)
    if verbose:
        print(response.url)
    return response
