def main():

    state_choices = ["present", "absent", "started", "stopped"]

    argument_spec = elastic_common_argument_spec()
    # TODO Add options from above
    argument_spec.update(
        name=dict(type='str', required=True),
        index_pattern=dict(type='str'),
        rollup_index=dict(type='str'),
        cron=dict(type='str'),
        page_size=dict(type='int', default=1000),
        groups=dict(type='dict'),
        metrics=dict(type='list', elements='dict'),
        state=dict(type='str', choices=state_choices, default='present'),
    )

    module = AnsibleModule(
        argument_spec=argument_spec,
        supports_check_mode=True,
        required_together=[['login_user', 'login_password']],
    )

    if not elastic_found:
        module.fail_json(msg=missing_required_lib('elasticsearch'),
                         exception=E_IMP_ERR)

    name = module.params['name']
    index_pattern = module.params['index_pattern']
    rollup_index = module.params['rollup_index']
    cron = module.params['cron']
    page_size = module.params['page_size']
    groups = module.params['groups']
    metrics = module.params['metrics']
    state = module.params['state']

    # values that should be supplied when passing state = present
    if state == 'present':
        check_param_state_present(module, index_pattern, "index_pattern")
        check_param_state_present(module, rollup_index, "rollup_index")
        check_param_state_present(module, cron, "cron")
        check_param_state_present(module, groups, "groups")
        check_param_state_present(module, metrics, "metrics")
        # Check that groups and metrics has the appropriate keys
        if len(
                set(list(groups.keys())) -
                set(["date_histogram", "histogram", "terms"])) > 0:
            module.fail_json(
                msg="There are invalid keys in the groups dictionary.")
        elif not isinstance(metrics, list):
            module.fail_json(msg="The metrics key does not contain a list.")

    # TODO main module logic
    try:
        elastic = ElasticHelpers(module)
        client = elastic.connect()

        job = get_rollup_job(client, name)

        # We can probably refector this code to reduce by 50% by only chekcing check ode when we actually change something
        if job is not None:  # Job exists
            job_config = job['config']
            job_status = job['status']
            if module.check_mode:
                if state == "present":
                    is_different = job_is_different(job_config, module)
                    if is_different > 0:
                        module.exit_json(
                            changed=True,
                            msg="The rollup job {0} definition was updated. {1}"
                            .format(name, is_different))
                    else:
                        module.exit_json(
                            changed=False,
                            msg=
                            "The rollup job {0} already exists and no updates were needed."
                            .format(name))
                elif state == "absent":
                    module.exit_json(
                        changed=True,
                        msg="The rollup job {0} was removed.".format(name))
                elif state == "started":
                    if job_config["status"]["job_state"] == "stopped":
                        module.exit_json(
                            changed=True,
                            msg="The rollup job {0} was started.".format(name))
                    elif job_config["status"]["job_state"] == "started":
                        module.exit_json(
                            changed=False,
                            msg=
                            "The rollup job {0} is already in a started state".
                            format(name))
                    else:
                        module.fail_jsob(
                            msg="Job {0} was in a unexpected state: {1}.".
                            format(name, state))
                elif state == "stopped":
                    if job_status["job_state"] == "started":
                        module.exit_json(
                            changed=True,
                            msg="The rollup job {0} was stopped.".format(name))
                    elif job_status["job_state"] == "stopped":
                        module.exit_json(
                            changed=False,
                            msg=
                            "The rollup job {0} is already in a stopped state".
                            format(name))
                    else:
                        module.fail_jsob(
                            msg="Job {0} was in a unexpected state: {1}.".
                            format(name, state))
            else:
                if state == "present":
                    is_different = job_is_different(job_config, module)
                    if is_different > 0:
                        module.exit_json(
                            changed=True,
                            msg="The rollup job {0} definition was updated. {1}"
                            .format(name, is_different))
                    else:
                        module.exit_json(
                            changed=False,
                            msg=
                            "The rollup job {0} already exists and no updates were needed."
                            .format(name))
                elif state == "absent":
                    response = client.rollup.delete_job(id=name)
                    module.exit_json(
                        changed=True,
                        msg="The rollup job {0} was removed.".format(name))
                elif state == "started":
                    if job_status["job_state"] == "stopped":
                        client.rollup.start_job(name)
                        module.exit_json(
                            changed=True,
                            msg="The rollup job {0} was started.".format(name))
                    elif job_status["job_state"] == "started":
                        module.exit_json(
                            changed=False,
                            msg=
                            "The rollup job {0} is already in a started state".
                            format(name))
                    else:
                        module.fail_jsob(
                            msg="Job {0} was in a unexpected state: {1}.".
                            format(name, state))
                elif state == "stopped":
                    if job_status["job_state"] == "started":
                        client.rollup.stop_job(name)
                        module.exit_json(
                            changed=True,
                            msg="The rollup job {0} was stopped.".format(name))
                    elif job_status["job_state"] == "stopped":
                        module.exit_json(
                            changed=False,
                            msg=
                            "The rollup job {0} is already in a stopped state".
                            format(name))
                    else:
                        module.fail_jsob(
                            msg="Job {0} was in a unexpected state: {1}.".
                            format(name, state))
        else:
            if module.check_mode:
                if state == "present":
                    module.exit_json(
                        changed=True,
                        msg="The rollup job {0} was created.".format(name))
                elif state == "absent":
                    module.exit_json(
                        changed=False,
                        msg="The rollup job {0} does not exist.".format(name))
                elif state in ["started", "stopped"]:
                    module.exit_json(
                        changed=False,
                        msg="Cannot stop or start a job that does not exist.")
            else:
                if state == "present":
                    body = {
                        "cron": cron,
                        "groups": groups,
                        "index_pattern": index_pattern,
                        "metrics": metrics,
                        "page_size": page_size,
                        "rollup_index": rollup_index
                    }
                    response = client.rollup.put_job(id=name,
                                                     body=body,
                                                     headers=None)
                    module.exit_json(
                        changed=True,
                        msg="The rollup job {0} was successfully created.".
                        format(name))
                elif state == "absent":
                    module.exit_json(
                        changed=False,
                        msg="The rollup job {0} does not exist.".format(name))
                elif state in ["started", "stopped"]:
                    module.exit_json(
                        changed=False,
                        msg="Cannot stop or start a job that does not exist.")

    except Exception as excep:
        module.fail_json(msg='Elastic error: %s' % to_native(excep))
def main():

    state_choices = [
        "present",
        "absent",
        "started",
        "stopped"
    ]

    argument_spec = elastic_common_argument_spec()
    # TODO Add options from above
    argument_spec.update(
        name=dict(type='str', required=True, aliases=['transform_id']),
        defer_validation=dict(type='bool', default=False),
        description=dict(type='str'),
        dest=dict(type='dict'),
        frequency=dict(type='str', default="1m"),
        latest=dict(type='dict'),
        pivot=dict(type='dict'),
        settings=dict(type='dict'),
        source=dict(type='dict'),
        sync=dict(type='dict'),
        state=dict(type='str', choices=state_choices, default='present'),
    )

    module = AnsibleModule(
        argument_spec=argument_spec,
        supports_check_mode=True,
        required_together=[['login_user', 'login_password']],
    )

    if not elastic_found:
        module.fail_json(msg=missing_required_lib('elasticsearch'),
                         exception=E_IMP_ERR)

    name = module.params['name']
    state = module.params['state']

    # values that should be supplied when passing state = present
    if state == 'present':
        check_param_state_present(module, "dest")
        check_param_state_present(module, "source")
    #    check_param_state_present(module, cron, "cron")
    #    check_param_state_present(module, groups, "groups")
    #    check_param_state_present(module, metrics, "metrics")
    # Check that groups and metrics has the appropriate keys
    #    if len(set(list(groups.keys())) - set(["date_histogram", "histogram", "terms"])) > 0:
    #        module.fail_json(msg="There are invalid keys in the groups dictionary.")
    #    elif not isinstance(metrics, list):
    #        module.fail_json(msg="The metrics key does not contain a list.")

    # TODO main module logic
    try:
        elastic = ElasticHelpers(module)
        client = elastic.connect()

        job = get_transform_job(client, name)

        # We can probably refector this code to reduce by 50% by only checking when we actually change something
        if job is not None:  # Job exists
            job_config = job
            job_status = get_transform_state(client, name)
            if module.check_mode:
                if state == "present":
                    is_different = job_is_different(job_config, module)
                    if is_different > 0:
                        module.exit_json(changed=True, msg="The transform job {0} definition was updated. {1}".format(name, is_different))
                    else:
                        module.exit_json(changed=False, msg="The transform job {0} already exists and no updates were needed.".format(name))
                elif state == "absent":
                    module.exit_json(changed=True, msg="The transform job {0} was removed.".format(name))
                elif state == "started":
                    if job_config["status"]["job_state"] == "stopped":
                        module.exit_json(changed=True, msg="The transform job {0} was started.".format(name))
                    elif job_config["status"]["job_state"] == "started":
                        module.exit_json(changed=False, msg="The transform job {0} is already in a started state".format(name))
                    else:
                        module.fail_jsob(msg="Job {0} was in a unexpected state: {1}.".format(name, state))
                elif state == "stopped":
                    if job_status == "started":
                        module.exit_json(changed=True, msg="The transform job {0} was stopped.".format(name))
                    elif job_status == "stopped":
                        module.exit_json(changed=False, msg="The transform job {0} is already in a stopped state".format(name))
                    else:
                        module.fail_jsob(msg="Job {0} was in a unexpected state: {1}.".format(name, state))
            else:
                if state == "present":
                    is_different = job_is_different(job_config, module)
                    if is_different > 0:
                        module.exit_json(changed=True, msg="The transform job {0} definition was updated. {1}".format(name, is_different))
                    else:
                        module.exit_json(changed=False, msg="The transform job {0} already exists and no updates were needed.".format(name))
                elif state == "absent":
                    response = client.transform.delete_transform(transform_id=name)
                    module.exit_json(changed=True, msg="The transform job {0} was removed.".format(name))
                elif state == "started":
                    if job_status == "stopped":
                        client.transform.start_transform(transform_id=name)
                        module.exit_json(changed=True, msg="The transform job {0} was started.".format(name))
                    elif job_status == "started":
                        module.exit_json(changed=False, msg="The transform job {0} is already in a started state".format(name))
                    else:
                        module.fail_jsob(msg="Job {0} was in a unexpected state: {1}.".format(name, state))
                elif state == "stopped":
                    if job_status == "started":
                        client.transform.stop_transform(transform_id=name)
                        module.exit_json(changed=True, msg="The transform job {0} was stopped.".format(name))
                    elif job_status == "stopped":
                        module.exit_json(changed=False, msg="The transform job {0} is already in a stopped state".format(name))
                    else:
                        module.fail_jsob(msg="Job {0} was in a unexpected state: {1}.".format(name, state))
        else:
            if module.check_mode:
                if state == "present":
                    module.exit_json(changed=True, msg="The transform job {0} was created.".format(name))
                elif state == "absent":
                    module.exit_json(changed=False, msg="The transform job {0} does not exist.".format(name))
                elif state in ["started", "stopped"]:
                    module.exit_json(changed=False, msg="Cannot stop or start a job that does not exist.")
            else:
                if state == "present":
                    body = {}
                    body_keys = [
                        "description",
                        "dest",
                        "frequency",
                        "latest",
                        "pivot",
                        "settings",
                        "source",
                        "sync"
                    ]
                    for key in body_keys:
                        body = add_if_not_none(body, key, module)
                    response = client.transform.put_transform(transform_id=name,
                                                              body=body,
                                                              headers=None,
                                                              defer_validation=module.params['defer_validation'])
                    module.exit_json(changed=True, msg="The transform job {0} was successfully created.".format(name))
                elif state == "absent":
                    module.exit_json(changed=False, msg="The transform job {0} does not exist.".format(name))
                elif state in ["started", "stopped"]:
                    module.exit_json(changed=False, msg="Cannot stop or start a job that does not exist.")

    except Exception as excep:
        module.fail_json(msg='Elastic error: %s' % to_native(excep))