#!/usr/bin/python
#
# Copyright (c) 2014-2015, Epic Games, Inc.
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later

from __future__ import annotations


DOCUMENTATION = r"""
module: circonus_annotation
short_description: Create an annotation in Circonus
description:
  - Create an annotation event with a given category, title and description. Optionally start, end or durations can be provided.
author: "Nick Harring (@NickatEpic)"
requirements:
  - requests >= 2.0.0
extends_documentation_fragment:
  - community.general.attributes
attributes:
  check_mode:
    support: none
  diff_mode:
    support: none
options:
  api_key:
    type: str
    description:
      - Circonus API key.
    required: true
  category:
    type: str
    description:
      - Annotation Category.
    required: true
  description:
    type: str
    description:
      - Description of annotation.
    required: true
  title:
    type: str
    description:
      - Title of annotation.
    required: true
  start:
    type: int
    description:
      - Unix timestamp of event start.
      - If not specified, it defaults to "now".
  stop:
    type: int
    description:
      - Unix timestamp of event end.
      - If not specified, it defaults to "now" + O(duration).
  duration:
    type: int
    description:
      - Duration in seconds of annotation.
    default: 0
"""
EXAMPLES = r"""
- name: Create a simple annotation event with a source, defaults to start and end time of now
  community.general.circonus_annotation:
    api_key: XXXXXXXXXXXXXXXXX
    title: App Config Change
    description: This is a detailed description of the config change
    category: This category groups like annotations

- name: Create an annotation with a duration of 5 minutes and a default start time of now
  community.general.circonus_annotation:
    api_key: XXXXXXXXXXXXXXXXX
    title: App Config Change
    description: This is a detailed description of the config change
    category: This category groups like annotations
    duration: 300

- name: Create an annotation with a start_time and end_time
  community.general.circonus_annotation:
    api_key: XXXXXXXXXXXXXXXXX
    title: App Config Change
    description: This is a detailed description of the config change
    category: This category groups like annotations
    start_time: 1395940006
    end_time: 1395954407
"""

RETURN = r"""
annotation:
  description: Details about the created annotation.
  returned: success
  type: complex
  contains:
    _cid:
      description: Annotation identifier.
      returned: success
      type: str
      sample: /annotation/100000
    _created:
      description: Creation timestamp.
      returned: success
      type: int
      sample: 1502236928
    _last_modified:
      description: Last modification timestamp.
      returned: success
      type: int
      sample: 1502236928
    _last_modified_by:
      description: Last modified by.
      returned: success
      type: str
      sample: /user/1000
    category:
      description: Category of the created annotation.
      returned: success
      type: str
      sample: alerts
    title:
      description: Title of the created annotation.
      returned: success
      type: str
      sample: WARNING
    description:
      description: Description of the created annotation.
      returned: success
      type: str
      sample: Host is down.
    start:
      description: Timestamp, since annotation applies.
      returned: success
      type: int
      sample: Host is down.
    stop:
      description: Timestamp, since annotation ends.
      returned: success
      type: str
      sample: Host is down.
    rel_metrics:
      description: Array of metrics related to this annotation, each metrics is a string.
      returned: success
      type: list
      sample:
        - 54321_kbps
"""

import json
import time
import traceback

from ansible_collections.community.general.plugins.module_utils.version import LooseVersion

REQUESTS_IMP_ERR = None
try:
    import requests

    HAS_REQUESTS = True
except ImportError:
    REQUESTS_IMP_ERR = traceback.format_exc()
    HAS_REQUESTS = False

from ansible.module_utils.basic import AnsibleModule, missing_required_lib
from ansible.module_utils.common.text.converters import to_native


def check_requests_dep(module):
    """Check if an adequate requests version is available"""
    if not HAS_REQUESTS:
        module.fail_json(msg=missing_required_lib("requests"), exception=REQUESTS_IMP_ERR)
    else:
        required_version = "2.0.0"
        if LooseVersion(requests.__version__) < LooseVersion(required_version):
            module.fail_json(
                msg=f"'requests' library version should be >= {required_version}, found: {requests.__version__}."
            )


def post_annotation(annotation, api_key):
    """Takes annotation dict and api_key string"""
    base_url = "https://api.circonus.com/v2"
    anootate_post_endpoint = "/annotation"
    resp = requests.post(base_url + anootate_post_endpoint, headers=build_headers(api_key), data=json.dumps(annotation))
    resp.raise_for_status()
    return resp


def create_annotation(module):
    """Takes ansible module object"""
    annotation = {}
    duration = module.params["duration"]
    if module.params["start"] is not None:
        start = module.params["start"]
    else:
        start = int(time.time())
    if module.params["stop"] is not None:
        stop = module.params["stop"]
    else:
        stop = int(time.time()) + duration
    annotation["start"] = start
    annotation["stop"] = stop
    annotation["category"] = module.params["category"]
    annotation["description"] = module.params["description"]
    annotation["title"] = module.params["title"]
    return annotation


def build_headers(api_token):
    """Takes api token, returns headers with it included."""
    headers = {
        "X-Circonus-App-Name": "ansible",
        "Host": "api.circonus.com",
        "X-Circonus-Auth-Token": api_token,
        "Accept": "application/json",
    }
    return headers


def main():
    """Main function, dispatches logic"""
    module = AnsibleModule(
        argument_spec=dict(
            start=dict(type="int"),
            stop=dict(type="int"),
            category=dict(required=True),
            title=dict(required=True),
            description=dict(required=True),
            duration=dict(default=0, type="int"),
            api_key=dict(required=True, no_log=True),
        )
    )

    check_requests_dep(module)

    annotation = create_annotation(module)
    try:
        resp = post_annotation(annotation, module.params["api_key"])
    except requests.exceptions.RequestException as e:
        module.fail_json(msg="Request Failed", reason=to_native(e), exception=traceback.format_exc())
    module.exit_json(changed=True, annotation=resp.json())


if __name__ == "__main__":
    main()
