#!/usr/bin/env python
# Copyright (c) 2022 Project CHIP Authors
#
# 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 os
import logging
import jinja2

from typing import Dict
from idl.matter_idl_types import Idl

from .filters import RegisterCommonFilters


class GeneratorStorage:
    """
    Handles file operations for generator output. Specifically can create
    required files for output.

    Is overriden for unit tests.
    """

    def __init__(self):
        self._generated_paths = set()

    @property
    def generated_paths(self):
        return self._generated_paths

    def report_output_file(self, relative_path: str):
        self._generated_paths.add(relative_path)

    def get_existing_data(self, relative_path: str):
        """Gets the existing data at the given path.
        If such data does not exist, will return None.
        """
        raise NotImplementedError()

    def write_new_data(self, relative_path: str, content: str):
        """Write new data to the given path."""
        raise NotImplementedError()


class FileSystemGeneratorStorage(GeneratorStorage):
    """
    A storage generator which will physically write files to disk into
    a given output folder.
    """

    def __init__(self, output_dir: str):
        super().__init__()
        self.output_dir = output_dir

    def get_existing_data(self, relative_path: str):
        """Gets the existing data at the given path.
        If such data does not exist, will return None.
        """
        target = os.path.join(self.output_dir, relative_path)

        if not os.path.exists(target):
            return None

        logging.info("Checking existing data in %s" % target)
        with open(target, 'rt') as existing:
            return existing.read()

    def write_new_data(self, relative_path: str, content: str):
        """Write new data to the given path."""

        target = os.path.join(self.output_dir, relative_path)
        target_dir = os.path.dirname(target)
        if not os.path.exists(target_dir):
            logging.info("Creating output directory: %s" % target_dir)
            os.makedirs(target_dir)

        logging.info("Writing new data to: %s" % target)
        with open(target, "wt") as out:
            out.write(content)


class CodeGenerator:
    """
    Defines the general interface for things that can generate code output.

    A CodeGenerator takes a AST as input (a `Idl` type) and generates files
    as output (like java/cpp/mm/other).

    Its public interface surface is reasonably small:
      'storage' init argument specifies where generated code goes
      'idl' is the input AST to generate
      'render' will perform a rendering of all files.

    As special optimizations, CodeGenerators generally will try to read
    existing data and will not re-write content if not changed (so that 
    write time of files do not change and rebuilds are not triggered).
    """

    def __init__(self, storage: GeneratorStorage, idl: Idl):
        """
        A code generator will render a parsed IDL (a AST) into a given storage.
        """
        self.storage = storage
        self.idl = idl
        self.jinja_env = jinja2.Environment(
            loader=jinja2.FileSystemLoader(searchpath=os.path.dirname(__file__)),
            keep_trailing_newline=True)
        self.dry_run = False

        RegisterCommonFilters(self.jinja_env.filters)

    def render(self, dry_run=False):
        """
        Renders  all required files given the idl contained in the code generator.
        Reset the list of generated outputs.

        Args:
          dry_run: if true, outputs are not actually written to disk.
                   if false, outputs are actually written to disk.
        """
        self.dry_run = dry_run
        self.internal_render_all()

    def internal_render_all(self):
        """This method is to be implemented by subclasses to run all generation
           as needed.
        """
        raise NotImplementedError("Method should be implemented by subclasses")

    def internal_render_one_output(self, template_path: str, output_file_name: str, vars: Dict):
        """
        Method to be called by subclasses to mark that a template is to be generated.

        File will either actually do a jinja2 generation or just log things
        if dry-run was requested during `render`.

        NOTE: to make this method suitable for rebuilds, this file will NOT alter
              the timestamp of the output file if the file content would not 
              change (i.e. no write will be invoked in that case.)

        Args:
          template_path - the path to the template to be loaded for file generation.
                          Template MUST be a jinja2 template.
          output_file_name - File name that the template is to be generated to.
          vars             - variables used for template generation
        """
        logging.info("File to be generated: %s" % output_file_name)
        if self.dry_run:
            return

        rendered = self.jinja_env.get_template(template_path).render(vars)

        # Report regardless if it has changed or not. This is because even if
        # files are unchanged, validation of what the correct output is should
        # still be done.
        self.storage.report_output_file(output_file_name)

        if rendered == self.storage.get_existing_data(output_file_name):
            logging.info("File content not changed")
        else:
            self.storage.write_new_data(output_file_name, rendered)
