#!/usr/bin/env python
# -*- coding: UTF-8 -*-
""" Add Graph Nodes to the OWL Model """


import os
from datetime import datetime

import pandas as pd
from baseblock import BaseObject, EnvIO, FileIO
from pandas import DataFrame
from rdflib import Graph, Namespace

from owl_builder.autorels.svc import (FindImpliesRelationships,
                                      FindRequiresRelationships,
                                      GenerateRelationshipsTTL)


class AddGraphNodes(BaseObject):
    """ Add Graph Nodes to the OWL Model """

    __authorship = "Generated on TIMESTAMP by AUTHOR"

    def __init__(self):
        """ Change Log:

        Created:
            21-Jul-20922
            craigtrim@gmail.com
            *   https://github.com/craigtrim/buildowl/issues/7
        """
        BaseObject.__init__(self, __name__)

    @staticmethod
    def _bump_version(lines: list) -> str:
        """ Increment the Minor Version Indicator
            all other increments must be performed by the author, manually

        Args:
            lines (list): all the graph lines

        Returns:
            str: the updated version only
        """

        def get_new_version(version_line: str) -> str:
            """ Get the new Version String
            Args:
                version_line (str): the incoming RDF line with the version
                    "owl:versionIRI <http://graffl.ai/template/0.1.0> ."

            Returns:
                str: the updated version only
            """
            current_version = version_line.split(
                "graffl.ai/")[-1].split("/")[-1].split('>')[0]
            tokens = str(current_version).split('.')
            return f"{tokens[0]}.{tokens[1]}.{int(tokens[2]) + 1}"

        for i in range(len(lines)):
            if "owl:versionIRI" in lines[i]:
                return get_new_version(lines[i])

        raise ValueError("No Version Defined")

    @staticmethod
    def _starting_line(lines: list) -> int:
        """ Find the Line to add new entities

        This isn't a big deal; the OWL is self-organizing when manually edited

        Args:
            lines (list): all the graph lines

        Returns:
            int: the preferred position to add new entities
        """
        for i in range(len(lines)):
            if lines[i].strip().startswith("###  Generated by the OWL API"):
                return i
            return len(lines) - 1

    def process(self,
                model_file_name: str,
                ttl_entities: list) -> str:
        """ Add new Entities in TTL (Turtle) format to the Model

        Args:
            model_file_name (str): the path to the existing model
            ttl_entities (list): the list of entities

        Returns:
            str: the new version
        """

        FileIO.exists_or_error(model_file_name)
        lines = FileIO.read_lines(model_file_name)

        version = self._bump_version(lines)
        start_on_line = self._starting_line(lines)

        normalized = []

        for i in range(len(lines)):

            if "owl:versionIRI" in lines[i]:
                vline = f"owl:versionIRI <http://graffl.ai/template/{version}> ."
                normalized.append(vline)
                continue

            if i == start_on_line:
                [normalized.append(x) for x in ttl_entities]

            normalized.append(lines[i])

        FileIO.write_lines(normalized, model_file_name)
        return version
