#!/usr/bin/env python3
import os
import __py_include

from datetime import datetime
from typing import Tuple, List, Optional
from argparse import ArgumentParser
from homekit.config import config, AppConfigUnit
from homekit.database import SimpleState
from homekit.api import WebApiClient


class OpenwrtLoggerConfig(AppConfigUnit):
    @classmethod
    def schema(cls) -> Optional[dict]:
        return dict(
            database_name_template=dict(type='string', required=True)
        )


def parse_line(line: str) -> Tuple[int, str]:
    space_pos = line.index(' ')

    date = line[:space_pos]
    rest = line[space_pos+1:]

    return (
        int(datetime.strptime(date, "%Y-%m-%dT%H:%M:%S%z").timestamp()),
        rest
    )


if __name__ == '__main__':
    parser = ArgumentParser()
    parser.add_argument('--file', type=str, required=True,
                        help='openwrt log file')
    parser.add_argument('--access-point', type=int, required=True,
                        help='access point number')

    arg = config.load_app(OpenwrtLoggerConfig, parser=parser)

    state = SimpleState(name=config.app_config['database_name_template'].replace('{ap}', str(arg.access_point)),
                        default=dict(seek=0, size=0))
    fsize = os.path.getsize(arg.file)
    if fsize < state['size']:
        state['seek'] = 0

    with open(arg.file, 'r') as f:
        if state['seek']:
            # jump to the latest read position
            f.seek(state['seek'])

        # read till the end of the file
        content = f.read()

        # save new position
        state['seek'] = f.tell()
        state['size'] = fsize

        lines: List[Tuple[int, str]] = []

        if content != '':
            for line in content.strip().split('\n'):
                if not line:
                    continue

                try:
                    lines.append(parse_line(line))
                except ValueError:
                    lines.append((0, line))

            api = WebApiClient()
            api.log_openwrt(lines, arg.access_point)
