from tendril.utils.config import ConfigOption
from tendril.utils import log
logger = log.get_logger(__name__, log.DEFAULT)

depends = ['tendril.config.core']


config_elements_app = [
    ConfigOption(
        'AUTH_ENABLE_LOGIN',
        "True",
        "Whether to enable login on this application. The type of this login depends "
        "on the configuration of the underlying auth provider. This is usually going to be "
        "True."
    ),
    ConfigOption(
        'AUTH_ENABLE_ADMIN',
        "True",
        "Whether user administration primitives are available on this application. "
        "This is currently required because Admin privileges are generally required for "
        "User Profile retrieval, and the ability to retrieve the user profile is "
        "presently assumed."
    ),
    ConfigOption(
        'AUTH_ENABLE_ADMIN_REALMS',
        "False",
        "Whether to Enable administration of other realms / clients / connections "
        "from this application. If true, ensure that the remote realms / clients / "
        "connections for the underlying auth providers are correctly configured. This "
        "is current generally used on Actual to manage device registration for iotedge."
    ),
    ConfigOption(
        'AUTH_REALMS',
        "[]",
        "Realms for which administration should be allowed from this application. "
        "This should only be configured on applications / components from which external "
        "realms need to be configured. Note that this presently is to be implemented in "
        "the underlying provider. The realm for the current application generally need not "
        "be included here, and the admin client for this realm is available with realm=None."
    ),
    ConfigOption(
        'SERVICES',
        "[]",
        "Services accessible to the application. These services are typically "
        "expected to be authenticated to with the client credentials grant. The necessary "
        "credentials may be configured for each service listed here as per the "
        "auth_services config construct.",
    )
]

config_elements_auth = [
    ConfigOption(
        'AUTH_PROVIDER',
        "'auth0'",
        "AuthN Provider"
    ),
    ConfigOption(
        'AUTHZ_PROVIDER',
        "AUTH_PROVIDER",
        "AuthZ Provider"
    ),
    ConfigOption(
        'AUTH_REALM',
        "None",
        "Realm to use for authentication. Required in multi-realm applications and when using "
        "providers which require realm specification such as keycloak."
    ),
    ConfigOption(
        "AUTH_AUDIENCE_BASE",
        "''",
        "Prefix for Audiences"
    ),
    ConfigOption(
        "AUTH_ISSUER_BASE",
        "'https://tendril.link/auth/'",
        "Prefix for Issuers"
    ),
    ConfigOption(
        "AUTH_COMPONENT",
        "COMPONENT_NAME",
        "Component for Audiences and Issuers"
    ),
    ConfigOption(
        "AUTH_AUDIENCE",
        "AUTH_AUDIENCE_BASE + AUTH_COMPONENT",
        "Audience required by client JWTs to interact with this component"
    ),
    ConfigOption(
        "AUTH_ISSUER",
        "AUTH_ISSUER_BASE + AUTH_COMPONENT",
        "Issuer specified in JWTs generated by this component"
    ),
    ConfigOption(
        'AUTH_PATCH_SCOPES_ON_STARTUP',
        'False',
        "Whether to patch scopes on the AuthZ provider at startup."
    ),
    ConfigOption(
        'AUTH_USERINFO_CACHING',
        "None",
        "Whether to cache userinfo acquired from the auth provider. "
        "Set to 'platform' for using platform-level caching, using redis. "
        "Other options not presently implemented."
    ),
    ConfigOption(
        'AUTH_INTRAMURAL_TOKEN_CACHING',
        "None",
        "Whether to cache intramural access tokens. This should generally "
        "be disabled for applications where security is a serious concern. "
        "Set to 'platform' for using platform-level caching, using redis. "
        "Other options not presently implemented."
    )
]

config_elements_jwt = [
    ConfigOption(
        'AUTH_JWT_API_ENABLED',
        "True",
        "Whether to enable JWT generation API"
    ),
    ConfigOption(
        'AUTH_JWKS_PATH',
        'os.path.join(INSTANCE_ROOT, "jwt", "jwks.json")',
        "Path to the jwks.json file to serve."
    ),
    ConfigOption(
        'AUTH_JWT_PRIVATE_KEY',
        'os.path.join(INSTANCE_ROOT, "jwt", "privateKey.pem")',
        "Path to the private key to use to sign JWTs."
    ),
    ConfigOption(
        'AUTH_JWT_PUBLIC_KEY',
        'os.path.join(INSTANCE_ROOT, "jwt", "publicKey.pem")',
        "Path to the public key to use to verify JWTs."
    ),
    ConfigOption(
        'AUTH_JWT_ISSUER',
        'AUTH_ISSUER',
        "Issuer to specify in the issued JWT claims."
    ),
    ConfigOption(
        'AUTH_JWT_TTL',
        '0',
        "TTL in seconds before the issued JWT can be used."
    ),
    ConfigOption(
        'AUTH_JWT_VALIDITY',
        '3600',
        "Duration in seconds before the issued JWT is expired."
    ),
    ConfigOption(
        'AUTH_JWT_ALGORITHMS',
        '["RS256", "ES256", "HS256"]',
        "Algorithm to use to sign or verify JWTs. The first element used for encode."
    )
]

# config_elements_mechanized = [
#     ConfigOption(
#         'AUTH_MECHANIZED_PROVIDER',
#         'AUTH_PROVIDER',
#         "Provider to use for mechanized users, if different."
#     ),
#     ConfigOption(
#         'AUTH_MECHANIZED_AUDIENCE',
#         'AUTH_AUDIENCE_BASE + iotedge',
#         "Audience to expect in the Mechanized Keycloak Tokens"
#     ),
#     ConfigOption(
#         'AUTH_MECHANIZED_USER_DOMAIN',
#         '"tendril.link"',
#         "Domain to use for mechanized user email addresses."
#     ),
# ]

def load(manager):
    logger.debug("Loading {0}".format(__name__))
    manager.load_elements(config_elements_app,
                          doc="Authentication Features Configuration",)
    manager.load_elements(config_elements_auth,
                          doc="Authentication Configuration")
    manager.load_elements(config_elements_jwt,
                          doc="JWT Infrastructure Configuration")
    # manager.load_elements(config_elements_mechanized,
    #                       doc="Mechanized Users Configuration")
