#!/usr/local/sbin/charm-env python3

# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements.  See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You 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.

import kafkautils
import subprocess

from charmhelpers.core import hookenv, host
from charms.reactive import is_state
from jujubigdata.utils import run_as
from time import time


if not is_state('kafka.started'):
    kafkautils.fail('Kafka service not yet ready')


# Define smoke test params
topic_name = "smoketest_{}".format(int(time()))
topic_partitions = 1
topic_replication = 1

# Smoke only when kafka is running
if host.service_available('kafka-server') and host.service_running('kafka-server'):
    # List ZKs
    zookeepers = kafkautils.get_zookeepers()
    if not zookeepers:
        kafkautils.fail('No zookeeper.connect string found')

    # Create a topic
    try:
        output = run_as('kafka', 'kafka-topics.sh',
                        '--zookeeper', zookeepers, '--create',
                        '--topic', topic_name,
                        '--partitions', topic_partitions,
                        '--replication-factor', topic_replication,
                        capture_output=True)
    except subprocess.CalledProcessError as e:
        kafkautils.fail('Kafka command failed: {}'.format(e.output))

    # List topics
    try:
        output = run_as('kafka', 'kafka-topics.sh',
                        '--zookeeper', zookeepers, '--list',
                        capture_output=True)
    except subprocess.CalledProcessError as e:
        kafkautils.fail('Kafka command failed: {}'.format(e.output))

    # If we haven't failed yet, we passed
    hookenv.action_set({'outcome': 'success'})
else:
    kafkautils.fail('kafka-server service is not running')
