#!/usr/bin/env python
# -*- coding: utf-8 -*-

# Copyright 2017 Novo Nordisk Foundation Center for Biosustainability,
# Technical University of Denmark.
#
# 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.

"""
`git` pre-commit hook that adds a YAML representation of the SBML model to the
commit if the model changed at all.
"""

from __future__ import absolute_import

import logging
import os.path as osp
from six.moves import configparser
from subprocess import check_output

from cobra.io import read_sbml_model, save_yaml_model


LOGGER = logging.getLogger("pre-commit")


def add_file(sbml_path, file_path, file_type):
    LOGGER.info("Reading SBML '%s'.", sbml_path)
    model = read_sbml_model(sbml_path)
    LOGGER.info("Writing {} '{}'.".format(file_type.upper(), file_path))
    if file_type == "yaml":
        save_yaml_model(model, file_path, sort=True)
    # Use subprocess rather than gitpython because gitpython cannot get a lock
    # on the git DB and thus raises an exception.
    check_output(["git", "add", file_path])


def main():
    config_path = osp.join(
        osp.dirname(__file__), osp.pardir, osp.pardir, "memote.ini")
    if not osp.exists(config_path):
        LOGGER.error(
            "No configuration file found. Expected '%s'. Skipping pre-commit.",
            config_path)
        return
    config = configparser.ConfigParser()
    config.read(config_path)
    model_path = config.get("memote", "model")
    if not osp.exists(model_path):
        LOGGER.warning("Model '%s' not found, skipping YAML addition.",
                       model_path)
        return
    yaml_path = config.get("pre_commit", "yaml")
    if yaml_path == "default":
        # Store the YAML output in the same location as the model file.
        yaml_path = osp.join(
            osp.dirname(model_path),
            osp.splitext(osp.basename(model_path))[0] + ".yml"
        )
    add_file(model_path, yaml_path, "yaml")


if __name__ == "__main__":
    logging.basicConfig(
        level="INFO", format="[%(name)s][%(levelname)s] %(message)s")
    main()
