# 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" + "<br>"
    
    # 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/<categorie>')
api.add_resource(Paheko_user, '/paheko/user/<ident>', endpoint='paheko_get_user', methods=['GET'])
api.add_resource(Paheko_user, '/paheko/user/<ident>/<string:field>/<string:new_value>', endpoint='paheko_maj_user', methods=['PUT'])
api.add_resource(Paheko_users_action, '/paheko/users/<string:action>')        

#*************************************************
#*******MATTERMOST********************************
#*************************************************

api.add_resource(Mattermost_message, '/mattermost/message/<equipe>/<canal>/<message>')
api.add_resource(Mattermost_user, '/mattermost/user/<string:user>', endpoint='mattermost_get_user', methods=['GET'])
api.add_resource(Mattermost_user, '/mattermost/user/create/<string:user>/<string:email>/<string:password>', endpoint='mattermost_create_user', methods=['POST'])
api.add_resource(Mattermost_user, '/mattermost/user/delete/<string:email>', endpoint='mattermost_delete_user', methods=['DELETE'])
api.add_resource(Mattermost_user, '/mattermost/user/change/password/<string:email>/<string:new_password>', endpoint='mattermost_change_user_password', methods=['PUT'])
api.add_resource(Mattermost_user_team, '/mattermost/user/team/<string:email>/<string:equipe>')
api.add_resource(Mattermost_user_channel, '/mattermost/user/channel/<string:email>/<string:equipe>/<string:canal>')
api.add_resource(Mattermost_team, '/mattermost/team/list',endpoint='mattermost_team_list', methods=['GET'])
api.add_resource(Mattermost_team, '/mattermost/team/create/<equipe>/<email>',endpoint='mattermost_team_create', methods=['POST'])
api.add_resource(Mattermost_team, '/mattermost/team/delete/<equipe>',endpoint='mattermost_team_delete', methods=['DELETE'])


#*************************************************
#***** LDAP **************************************
#*************************************************

api.add_resource(Ldap_user, '/ldap/user/<string:email>', endpoint='ldap_user_get', methods=['GET'])
api.add_resource(Ldap_user, '/ldap/user/delete/<string:email>', endpoint='ldap_user_delete', methods=['DELETE'])
api.add_resource(Ldap_user, '/ldap/user/change/<string:email>', endpoint='ldap_user_change', methods=['POST'])
api.add_resource(Ldap_user, '/ldap/user/add/<string:email>', endpoint='ldap_user_add', methods=['PUT'])

#*************************************************
#***** CLOUD **************************************
#*************************************************

api.add_resource(Cloud_user, '/cloud/user/<string:email>')
api.add_resource(Cloud_user_delete, '/cloud/user/delete/<string:email>')
# api.add_resource(Cloud_user_change, '/cloud/user/change/<string:email>/<string:new_password>')

#*************************************************
#***** SYMPA **************************************
#*************************************************

api.add_resource(Sympa_user, '/sympa/user/<string:email>/<string:liste>')   

#*************************************************
#***** QUOTA **************************************
#*************************************************

api.add_resource(Quota, '/quota/<string:email>') 

#*************************************************
#***** DNS **************************************
#*************************************************

api.add_resource(Dns, '/dns/<string:sdomaine>', endpoint='dns_get', methods=['GET'])
api.add_resource(Dns, '/dns/<string:sdomaine>', endpoint='dns_delete', methods=['DELETE'])
api.add_resource(Dns, '/dns/<string:sdomaine>/<string:serveur>', 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'))