/*
 * JBoss, Home of Professional Open Source.
 * Copyright 2022 Red Hat, Inc., and individual contributors
 * as indicated by the @author tags.
 *
 * 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.
 */

package org.jboss.installer.validators;

import org.apache.commons.lang3.StringUtils;
import org.jboss.installer.core.LanguageUtils;
import org.jboss.installer.core.ValidationResult;
import org.jboss.installer.postinstall.task.secdom.KerberosSecurity;
import org.wildfly.security.asn1.OidsUtil;

import static org.jboss.installer.screens.domain.KerberosSecurityDomainPanel.FILESYSTEM_REALM_NAME_LABEL;
import static org.jboss.installer.screens.domain.KerberosSecurityDomainPanel.FILESYSTEM_REALM_PATH_LABEL;
import static org.jboss.installer.screens.domain.KerberosSecurityDomainPanel.IDENTITY_ATTRIBUTE_NAME_LABEL;
import static org.jboss.installer.screens.domain.KerberosSecurityDomainPanel.IDENTITY_ATTRIBUTE_VALUE_LABEL;
import static org.jboss.installer.screens.domain.KerberosSecurityDomainPanel.IDENTITY_NAME_LABEL;
import static org.jboss.installer.screens.domain.KerberosSecurityDomainPanel.KERBEROS_SECURITY_FACTORY_NAME_LABEL;
import static org.jboss.installer.screens.domain.KerberosSecurityDomainPanel.KEYTAB_PATH_LABEL;
import static org.jboss.installer.screens.domain.KerberosSecurityDomainPanel.KRB5_CONF_FILE_LABEL;
import static org.jboss.installer.screens.domain.KerberosSecurityDomainPanel.PRINCIPAL_LABEL;
import static org.jboss.installer.screens.domain.KerberosSecurityDomainPanel.SIMPLE_ROLE_DECODER_ATTRIBUTE_LABEL;
import static org.jboss.installer.screens.domain.KerberosSecurityDomainPanel.SIMPLE_ROLE_DECODER_NAME_LABEL;
import static org.jboss.installer.validators.CertificateSecurityDomainValidator.GENERIC_VALIDATION_EMPTY_FIELD;

public class KerberosSecurityDomainValidator {

    static final String UNSUPPORTED_MECHANISM_NAME_ERROR = "security_domain_screen.kerberos.unsupported.mechanism.names.error";
    static final String UNSUPPORTED_MECHANISM_OID_ERROR = "security_domain_screen.kerberos.unsupported.mechanism.oids.error";
    private final LanguageUtils langUtils;
    private final FileValidator fileValidator;

    public KerberosSecurityDomainValidator(LanguageUtils langUtils) {
        this.langUtils = langUtils;
        this.fileValidator = new FileValidator(langUtils);
    }

    public ValidationResult validate(KerberosSecurity.KerberosConfig config) {
        // validate kerberos-security-factory attributes
        if (StringUtils.isEmpty(config.getKerberosSecurityFactoryName())) {
            return ValidationResult.error(langUtils.getString(GENERIC_VALIDATION_EMPTY_FIELD, langUtils.getString(KERBEROS_SECURITY_FACTORY_NAME_LABEL)));
        }
        if (StringUtils.isEmpty(config.getPrincipal())) {
            return ValidationResult.error(langUtils.getString(GENERIC_VALIDATION_EMPTY_FIELD, langUtils.getString(PRINCIPAL_LABEL)));
        }
        if (config.getKeyTabPath() == null) {
            return ValidationResult.error(langUtils.getString(GENERIC_VALIDATION_EMPTY_FIELD, langUtils.getString(KEYTAB_PATH_LABEL)));
        }
        ValidationResult res = fileValidator.validate(config.getKeyTabPath());
        if (res.getResult() != ValidationResult.Result.OK) {
            return res;
        }
        for (String name : config.getMechanismNames()) {
            if (OidsUtil.attributeNameToOid(OidsUtil.Category.GSS, name) == null) {
                return ValidationResult.error(langUtils.getString(UNSUPPORTED_MECHANISM_NAME_ERROR, name));
            }
        }
        for (String oid : config.getMechanismOids()) {
            if (OidsUtil.oidToAttributeName(OidsUtil.Category.GSS, oid) == null) {
                return ValidationResult.error(langUtils.getString(UNSUPPORTED_MECHANISM_OID_ERROR, oid));
            }
        }

        // validate system properties for Kerberos
        if (config.getKrb5Conf() == null) {
            return ValidationResult.error(langUtils.getString(GENERIC_VALIDATION_EMPTY_FIELD, langUtils.getString(KRB5_CONF_FILE_LABEL)));
        }
        res = fileValidator.validate(config.getKrb5Conf());
        if (res.getResult() != ValidationResult.Result.OK) {
            return res;
        }

        // validate Elytron filesystem-realm attributes
        if (StringUtils.isEmpty(config.getFileSystemRealmName())) {
            return ValidationResult.error(langUtils.getString(GENERIC_VALIDATION_EMPTY_FIELD, langUtils.getString(FILESYSTEM_REALM_NAME_LABEL)));
        }
        if (StringUtils.isEmpty(config.getFileSystemRealmPath())) {
            return ValidationResult.error(langUtils.getString(GENERIC_VALIDATION_EMPTY_FIELD, langUtils.getString(FILESYSTEM_REALM_PATH_LABEL)));
        }
        if (StringUtils.isEmpty(config.getIdentityName())) {
            return ValidationResult.error(langUtils.getString(GENERIC_VALIDATION_EMPTY_FIELD, langUtils.getString(IDENTITY_NAME_LABEL)));
        }
        if (StringUtils.isEmpty(config.getIdentityAttributeName())) {
            return ValidationResult.error(langUtils.getString(GENERIC_VALIDATION_EMPTY_FIELD, langUtils.getString(IDENTITY_ATTRIBUTE_NAME_LABEL)));
        }
        if (config.getIdentityAttributeValue() == null || config.getIdentityAttributeValue().length == 0) {
            return ValidationResult.error(langUtils.getString(GENERIC_VALIDATION_EMPTY_FIELD, langUtils.getString(IDENTITY_ATTRIBUTE_VALUE_LABEL)));
        }

        // validate simple-role-decoder attributes
        if (StringUtils.isEmpty(config.getSimpleRoleDecoderName())) {
            return ValidationResult.error(langUtils.getString(GENERIC_VALIDATION_EMPTY_FIELD, langUtils.getString(SIMPLE_ROLE_DECODER_NAME_LABEL)));
        }
        if (StringUtils.isEmpty(config.getSimpleRoleDecoderAttribute())) {
            return ValidationResult.error(langUtils.getString(GENERIC_VALIDATION_EMPTY_FIELD, langUtils.getString(SIMPLE_ROLE_DECODER_ATTRIBUTE_LABEL)));
        }

        return ValidationResult.ok();
    }
}
