# ======================================================================
# Copyright 2026 Julien LE CLEACH
#
# Licensed 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 logging
import sys

from argparse import ArgumentParser, ArgumentTypeError
from configparser import ConfigParser

from supvisors.initializer import LOGGER_FORMAT
from supvisors.statscollector import *

logger = logging.getLogger(__name__)
logging.basicConfig(level=logging.INFO, format=LOGGER_FORMAT)
# TODO: configure stderr

# TODO: how to get all Supvisors processes?
#       initial get_all_proc + event subscribe (Supvisors ou Supervisor) ?
#       periodic get_all_proc ?
#       events.unsubscribe(events.ProcessStateEvent, self.on_process_state)

#[eventlistener:supvisors_stats]
#command=python -m supvisors.tools.supvisorsstats --enable-host --enable-process
#events=PROCESS_STATE
#buffer_size=50
#autostart=true
#autorestart=unexpected
#startsecs=1
#stderr_logfile=./log/%(program_name)s_%(host_node_name)s_err.log



# TODO: HOWTO publish to all Supvisors instances?
#       send to local and dispatch?
#       => InternalEventHeaders.NOTIFICATION
#       NotificationHeaders.HOST_STATS + NotificationHeaders.PROCESS_STATS

def write_stdout(s):
    # only eventlistener protocol messages may be sent to stdout
    sys.stdout.write(s)
    sys.stdout.flush()


def write_stderr(s):
    sys.stderr.write(s)
    sys.stderr.flush()


def to_period(value: str) -> float:
    """ Convert a string into a period value in [1.0 ; 3600.0] seconds. """
    try:
        period = float(value)
        if 1.0 > period or period > 3600.0:
            raise ValueError
        return period
    except ValueError:
        raise ArgumentTypeError(f'invalid period value: "{value}". float expected in [1.0;3600.0] (seconds)')


def parse_args(args):
    """ Parse arguments got from the command line.

    :param args: the command line arguments
    :return: the parsed arguments
    """
    parser = ArgumentParser(description='Collect and send Host/Process statistics to Supvisors')
    parser.add_argument('--enable-host', action='store_true', help='enable the collection of Host statistics')
    parser.add_argument('--host-collecting-period', type=to_period, default=5.0,
                        help='the period for collecting Host statistics')
    parser.add_argument('--enable-process', action='store_true', help='enable the collection of Process statistics')
    parser.add_argument('--process-collecting-period', type=to_period, default=5.0,
                        help='the period for collecting Process statistics')
    parser.add_argument('-v', '--verbose', action='store_true', help='activate DEBUG log traces')
    return parser.parse_args(args)


def main():
    """ Entry point of the program. """
    args = parse_args(sys.argv[1:])
    if args.verbose:
        logger.info(f'ArgumentParser: {args}')
    # TODO: configure
    while 1:
        # transition from ACKNOWLEDGED to READY
        write_stdout('READY\n')
        # read header line and print it to stderr
        line = sys.stdin.readline()
        write_stderr(line)
        # read event payload and print it to stderr
        headers = dict([x.split(':') for x in line.split()])
        data = sys.stdin.read(int(headers['len']))
        if headers['eventname'] != 'REMOTE_COMMUNICATION':
            write_stderr(data)
        # transition from READY to ACKNOWLEDGED
        write_stdout('RESULT 2\nOK')
