# Copyright 2022-2025 ETSI SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/)
#
# 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 logging
from flask import abort, jsonify, make_response, request
from flask_restful import Resource
from uuid import uuid4

LOG_LEVEL    = logging.DEBUG

logging.basicConfig(level=LOG_LEVEL, format="[%(asctime)s] %(levelname)s:%(name)s:%(message)s")
LOGGER = logging.getLogger(__name__)

logging.getLogger('werkzeug').setLevel(logging.INFO)

OSM_NSI = []

OSM_VIM_DB =  [
        {
            "_id": "account1",
            "name": "account1",
            "vim_type": "account1",
            "tenant": "account1",
            "vim_url": "http://account1.local"
        }
    ]


class OsmNST(Resource):
    def get(self):
        LOGGER.info("get NST request received")
        mock_nsts = [
            {
                "_id": "nst1",
                "name": "nst1",
                "description": "Nst_Mock",
                "vendor": "ExampleVendor",
                "version": "1.0"
            },
            {
                "_id": "nst2",
                "name": "nst2",
                "description": "Nst_Mock",
                "vendor": "AnotherVendor",
                "version": "2.1"
            }
        ]
        return make_response(jsonify(mock_nsts), 200)

class OsmNBI(Resource):
    def get(self):
        LOGGER.info("get NBI request received")

        LOGGER.info(str(OSM_NSI))

        return [nsi["id"] for nsi in OSM_NSI]

    def post(self):
        LOGGER.info("post request received")

        LOGGER.info(str(request))

        payload = request.get_json(silent=True) or {}
        qs      = request.args

        nst_id  = payload.get("nstId") or qs.get("nstId")
        name    = payload.get("nsiName") or qs.get("nsiName")
        desc    = payload.get("nsiDescription") or qs.get("nsiDescription", "")

        new_nsi = {
            "id": str(uuid4()),
            "name": name,
            "nstId": nst_id,
            "description": desc,
            "operationalStatus": "CREATED"
        }

        OSM_NSI.append(new_nsi)

        return make_response(jsonify(new_nsi), 201)


class VimAccounts(Resource):
    """
    Mock -> /osm/admin/v1/vim_accounts
    Support:
      • GET    → get all VIM Account
      • POST   → Create a VIM Account
    """
    def get(self):
        return jsonify(OSM_VIM_DB)

    def post(self):
        payload = request.get_json(silent=True) or {}
        name      = payload.get("name")
        vim_type  = payload.get("vim_type")

        if not name or not vim_type:
            return {"error": "name and vim_type are required"}, 400

        new_vim = {
            "_id": str(uuid4()),
            "name": name,
            "vim_type": vim_type,
            "tenant": payload.get("tenant", "admin"),
            "vim_url": payload.get("vim_url", "http://mock.local")
        }

        # Store new_vim in local DDBB
        OSM_VIM_DB.append(new_vim)
        return jsonify(new_vim), 201


class VimAccountItem(Resource):
    """
    Mock -> /osm/admin/v1/vim_accounts/<account_id>
    Support:
      • GET    → get VIM Account
      • PUT    → Upadate fields
      • DELETE → Delete VIM Account
    """

    @staticmethod
    def _find(account_id):
        """Search VIM account"""
        return next(
            (acc for acc in OSM_VIM_DB if acc["_id"] == account_id),
            None
        )

    # ------------------------
    # GET /vim_accounts/<id>
    # ------------------------
    def get(self, account_id):
        account = self._find(account_id)
        if not account:
            return {"error": "not found"}, 404
        return jsonify(account)

    # ------------------------
    # PUT /vim_accounts/<id>
    # ------------------------
    def put(self, account_id):
        account = self._find(account_id)
        if not account:
            return {"error": "not found"}, 404

        payload = request.get_json(silent=True) or {}
        for field in ("name", "vim_type", "tenant", "vim_url"):
            if field in payload:
                account[field] = payload[field]

        return jsonify(account)

    # ------------------------
    # DELETE /vim_accounts/<id>
    # ------------------------
    def delete(self, account_id):
        account = self._find(account_id)
        if not account:
            return {"error": "not found"}, 404

        OSM_VIM_DB.remove(account)
        return "", 204
