# Copyright 2017-present Open Networking Foundation
#
# 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 ast


def xproto_check_synchronizer(m):
    try:
        sync_step_path = "synchronizer/steps/sync_%s.py" % m["name"].lower()
        sync_step = open(sync_step_path).read()
    except IOError:
        return "510 Model needs a sync step %s" % sync_step_path

    try:
        sync_step_ast = ast.parse(sync_step)
    except SyntaxError:
        return "511 Could not parse sync step %s" % sync_step_path

    classes = filter(lambda x: isinstance(x, ast.ClassDef), sync_step_ast.body)
    found_sync_step_class = False

    for c in classes:
        base_names = [v.id for v in c.bases]
        if "SyncStep" in base_names or "SyncInstanceUsingAnsible" in base_names:
            attributes = filter(lambda x: isinstance(x, ast.Assign), c.body)
            for a in attributes:
                target_names = [t.id for t in a.targets]
                values = a.value.elts if isinstance(a.value, ast.List) else [a.value]
                value_names = [v.id for v in values]

                if "observes" in target_names and m["name"] in value_names:
                    found_sync_step_class = True
                    break

    if not found_sync_step_class:
        return (
            "512 Synchronizer needs a sync step class with an observes field containing %s"
            % m["name"]
        )
    else:
        return "200 OK"


def xproto_check_policy(m):
    try:
        model_policy_path = (
            "synchronizer/model_policies/model_policy_%s.py" % m["name"].lower()
        )
        model_policy = open(model_policy_path).read()
    except IOError:
        return "510 Model needs a model policy %s" % model_policy_path

    try:
        model_policy_ast = ast.parse(model_policy)
    except SyntaxError:
        return "511 Could not parse sync step %s" % model_policy_path

    classes = filter(lambda x: isinstance(x, ast.ClassDef), model_policy_ast.body)
    found_model_policy_class = False
    for c in classes:
        base_names = [v.id for v in c.bases]
        if "Policy" in base_names or "TenantWithContainerPolicy" in base_names:
            found_model_policy_class = True
            break

    if not found_model_policy_class:
        return "513 Synchronizer needs a model policy class"
    else:
        return "200 OK"
