# Importer tous les modules depuis common_imports (c'est là où il faut rajouter des modules python manquant)
from resources.common_imports import *
# Importer toutes les classes de kaz
from resources.password import Password_create
from resources.paheko import Paheko_categories, Paheko_users, Paheko_user, Paheko_users_action
from resources.mattermost import Mattermost_authenticate,  Mattermost_user, Mattermost_message, Mattermost_user_team, Mattermost_user_channel, Mattermost_team
from resources.ldap import Ldap_user
from resources.cloud import Cloud_user, Cloud_user_delete
from resources.sympa import Sympa_user
from resources.quota import Quota
from resources.dns import Dns_serveurs, Dns
from resources.kaz_user import Kaz_user
from resources.test import Test
#on importe toutes les variables globales
from resources.config import *
app = Flask(__name__)
jwt = JWTManager(app)
api = Api(app)
#comment qu'on log ? (TODO:faudrait coller ça dans le docker-compose.yml)
app.logger.setLevel(logging.DEBUG)
#on décrit l'api telle qu'elle apparait dans le swagger (la doc)
swagger = Swagger(app, template={
    "swagger": "2.0",
    "info": {
        "title": "L'API Kaz de la mort qui tue",
        "version": "0.2.0",
        "description": "Permettre des opérations de gestion des services kaz avec des écrans Ouaib"
    },
    "tags": [
        {"name": "Authentication", "description": "Auth related operations"},
        {"name": "Test", "description": "pour tester des conneries"},
        {"name": "Password", "description": "Gestion Mdp"},
        {"name": "Paheko", "description": "Gestion Paheko"},
        {"name": "Mattermost", "description": "Gestion Mattermost Authent"},
        {"name": "Mattermost User", "description": "Gestion Mattermost User"},
        {"name": "Mattermost Team", "description": "Gestion Mattermost Team"},
        {"name": "Ldap", "description": "Gestion Ldap"},
        {"name": "Cloud", "description": "Gestion Cloud Général"},
        {"name": "Sympa", "description": "Gestion Sympa"},
        {"name": "Quota", "description": "Gestion Quota"},
        {"name": "Dns", "description": "Gestion Dns"},
        {"name": "Kaz User", "description": "Gestion Kaz User"}        
    ],
    "securityDefinitions": {
          "basicAuth": {
              "type": "basic",
              "description": "Basic Authentication with username and password"
          },
          "Bearer": {
              "type": "apiKey",
              "name": "Authorization",
              "in": "header",
              "description": "JWT Authorization header using the Bearer scheme. Example: 'Bearer {token}'"
          }
      }      
})
        
#TODO:
# check variables
# fail2ban (ou alors sur traefik: https://github.com/tomMoulard/fail2ban)
# quels scripts bash garder ?
#fin TODO
#*************************************************
#Filtrer les IP qui peuvent accéder à l'api
#fait par traeffik
# trusted_ips = [
# "1.2.3.4",
# ]
   
   
#*************************************************
#variables globales
#*************************************************
#le secret pour générer les tokens
#app.config['JWT_SECRET_KEY'] = os.environ.get('JWT_SECRET_KEY')
app.config['JWT_SECRET_KEY'] = os.environ.get('JWT_SECRET_KEY', 'your_jwt_secret_key')
app.config['JWT_ACCESS_TOKEN_EXPIRES'] = timedelta(days=7)
#pour le mail
app.config['MAIL_SERVER']= os.environ.get('apikaz_MAIL_SERVER')
app.config['MAIL_PORT'] = 587
app.config['MAIL_USERNAME'] = os.environ.get('apikaz_MAIL_USERNAME')
app.config['MAIL_PASSWORD'] = os.environ.get('apikaz_MAIL_PASSWORD')
app.config['MAIL_REPLY_TO'] = os.environ.get('apikaz_MAIL_REPLY_TO')
app.config['MAIL_USE_TLS'] = True
app.config['MAIL_USE_SSL'] = False
mail = Mail(app)
#*************************************************
# @app.before_request
# def limit_remote_addr():    
#     if request.environ['HTTP_X_FORWARDED_FOR'] not in trusted_ips:
#         abort(jsonify(message="Et pis quoi encore ?"), 400)
#*************************************************
#authent mdp/pass basique
def check_auth(username, password):
    return username == os.environ.get('apikaz_doc_user') and password == os.environ.get('apikaz_doc_password')
    #return True
def authenticate():
    return Response('tssssss.\n', 401, {'WWW-Authenticate': 'Basic realm="Login Required"'})
@app.before_request
def require_basic_auth():
    if request.path.startswith('/apidocs') or request.path.startswith('/print_env'):
    #if request.path.startswith('/'):
        auth = request.authorization
        if not auth or not check_auth(auth.username, auth.password):
            return  authenticate()
#*************************************************
#DANGER: ne jamais mettre print_env en PROD
@app.route('/print_env')
def print_environment():
    # Crée une chaîne de caractères pour stocker les variables d'environnement
    env_string = ""
    
    # Itère sur les variables d'environnement et les ajoute à la chaîne de caractères
    for key, value in os.environ.items():
        env_string += f"{key}: {value}\n" + "
"
    
    # Retourne la chaîne de caractères contenant les variables d'environnement
    return env_string
#*************************************************
#***** DEBUT Quelques fonctions utiles ***********
#*************************************************
#pour injecter la date dans dans le contexte des template
@app.context_processor
def inject_now():
    return {'now': datetime.now}
  
#*************************************************
#***** FIN Quelques fonctions utiles ***********
#*************************************************
#*************************************************
@app.route('/favicon.ico')
def favicon():
    # return send_from_directory(os.path.join(app.root_path, 'static'),'favicon.ico')
    return '', 204
    
#*************************************************
#la page d'accueil est vide
@app.route('/')
def silence():
  return ""
#*************************************************
# obtenir un token
@app.route('/get_token', methods=['GET'])
def get_token():
    """
    Get JWT token with basic auth
    ---
    tags:
      - Authentication
    security:
      - basicAuth: []      
    responses:
      200:
        description: Token generated successfully
        schema:
          type: object
          properties:
            access_token:
              type: string
              description: JWT access token
      401:
        description: Unauthorized
    """
    auth = request.authorization
    if auth and check_auth(auth.username, auth.password):
        # Créez un token JWT après une authentification réussie
        access_token = create_access_token(identity=auth.username)
        return jsonify(access_token=access_token)
    else:
        return authenticate()
    
#*************************************************
#*******MDP***************************************
#*************************************************
api.add_resource(Password_create, '/password/create')
#*************************************************
#*******PAHEKO************************************
#*************************************************
api.add_resource(Paheko_categories, '/paheko/user/categories')
api.add_resource(Paheko_users, '/paheko/user/category/')
api.add_resource(Paheko_user, '/paheko/user/', endpoint='paheko_get_user', methods=['GET'])
api.add_resource(Paheko_user, '/paheko/user///', endpoint='paheko_maj_user', methods=['PUT'])
api.add_resource(Paheko_users_action, '/paheko/users/')        
#*************************************************
#*******MATTERMOST********************************
#*************************************************
api.add_resource(Mattermost_message, '/mattermost/message///')
api.add_resource(Mattermost_user, '/mattermost/user/', endpoint='mattermost_get_user', methods=['GET'])
api.add_resource(Mattermost_user, '/mattermost/user/create///', endpoint='mattermost_create_user', methods=['POST'])
api.add_resource(Mattermost_user, '/mattermost/user/delete/', endpoint='mattermost_delete_user', methods=['DELETE'])
api.add_resource(Mattermost_user, '/mattermost/user/change/password//', endpoint='mattermost_change_user_password', methods=['PUT'])
api.add_resource(Mattermost_user_team, '/mattermost/user/team//')
api.add_resource(Mattermost_user_channel, '/mattermost/user/channel///')
api.add_resource(Mattermost_team, '/mattermost/team/list',endpoint='mattermost_team_list', methods=['GET'])
api.add_resource(Mattermost_team, '/mattermost/team/create//',endpoint='mattermost_team_create', methods=['POST'])
api.add_resource(Mattermost_team, '/mattermost/team/delete/',endpoint='mattermost_team_delete', methods=['DELETE'])
#*************************************************
#***** LDAP **************************************
#*************************************************
api.add_resource(Ldap_user, '/ldap/user/', endpoint='ldap_user_get', methods=['GET'])
api.add_resource(Ldap_user, '/ldap/user/delete/', endpoint='ldap_user_delete', methods=['DELETE'])
api.add_resource(Ldap_user, '/ldap/user/change/', endpoint='ldap_user_change', methods=['POST'])
api.add_resource(Ldap_user, '/ldap/user/add/', endpoint='ldap_user_add', methods=['PUT'])
#*************************************************
#***** CLOUD **************************************
#*************************************************
api.add_resource(Cloud_user, '/cloud/user/')
api.add_resource(Cloud_user_delete, '/cloud/user/delete/')
# api.add_resource(Cloud_user_change, '/cloud/user/change//')
#*************************************************
#***** SYMPA **************************************
#*************************************************
api.add_resource(Sympa_user, '/sympa/user//')   
#*************************************************
#***** QUOTA **************************************
#*************************************************
api.add_resource(Quota, '/quota/') 
#*************************************************
#***** DNS **************************************
#*************************************************
api.add_resource(Dns, '/dns/', endpoint='dns_get', methods=['GET'])
api.add_resource(Dns, '/dns/', endpoint='dns_delete', methods=['DELETE'])
api.add_resource(Dns, '/dns//', endpoint='dns_post', methods=['POST'])
api.add_resource(Dns_serveurs, '/dns/')
#*************************************************
#***** KAZ **************************************
#*************************************************
api.add_resource(Kaz_user, '/kaz/create/users', endpoint='kaz_create_user', methods=['POST'])
api.add_resource(Kaz_user, '/kaz/delete/user', endpoint='kaz_delete_user', methods=['DELETE'])
#*************************************************
#**********TEST***********************************
#*************************************************
api.add_resource(Test, '/test', endpoint='test', methods=['GET'])
#*************************************************
#*************************************************
#*************************************************
if __name__ == '__main__':
    app.run(host='0.0.0.0', port=os.getenv('PORT'))