/*
 * JBoss, Home of Professional Open Source.
 * Copyright 2024 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.postinstall.task.secdom;

import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

public class CertificateConfig {
    // serialization keys
    private static final String FILTER_EXPRESSION = "filterExpression";
    private static final String APPLICATION_DOMAIN_NAME = "applicationDomainName";
    private static final String TRUST_STORE_PATH = "trustStorePath";
    private static final String MAX_SEGMENTS = "maxSegments";
    private static final String START_SEGMENTS = "startSegments";
    private static final String USE_OID = "useOid";
    private static final String ROLE = "role-";
    private static final String ROLE_COUNT = "role-count";
    public static final String TRUST_STORE_PASSWORD_KEY = "trustStorePassword";
    // end of serialization keys

    private String applicationDomainName;
    private String[] roles;
    private Integer maximumSegments;
    private Integer startSegments;
    private String filterExpression;
    private Path trustStorePath;
    private String trustStorePassword;
    private boolean useOid;

    public CertificateConfig() {

    }

    public CertificateConfig(Map<String, String> attributes) {
        this.filterExpression = attributes.get(FILTER_EXPRESSION);
        this.applicationDomainName = attributes.get(APPLICATION_DOMAIN_NAME);
        this.trustStorePath = Paths.get(attributes.get(TRUST_STORE_PATH));
        this.maximumSegments = Integer.parseInt(attributes.get(MAX_SEGMENTS));
        this.startSegments = Integer.parseInt(attributes.get(START_SEGMENTS));
        this.useOid = Boolean.parseBoolean(attributes.get(USE_OID));
        this.trustStorePassword = attributes.get(TRUST_STORE_PASSWORD_KEY);

        final int roleCount = Integer.parseInt(attributes.get(ROLE_COUNT));
        final ArrayList<String> roles = new ArrayList<>(roleCount);
        for (int i = 0; i < roleCount; i++) {
            roles.add(attributes.get(ROLE + i));
        }
        this.roles = roles.toArray(new String[]{});
    }

    public void setApplicationDomainName(String applicationDomainName) {
        this.applicationDomainName = applicationDomainName;
    }

    public String getApplicationDomainName() {
        return applicationDomainName;
    }

    public String[] getRoles() {
        return roles;
    }

    public void setRoles(String[] roles) {
        this.roles = roles;
    }

    public Integer getMaximumSegments() {
        return maximumSegments;
    }

    public void setMaximumSegments(Integer maximumSegments) {
        this.maximumSegments = maximumSegments;
    }

    public Integer getStartSegments() {
        return startSegments;
    }

    public void setStartSegments(Integer startSegments) {
        this.startSegments = startSegments;
    }

    public String getFilterExpression() {
        return filterExpression;
    }

    public void setFilterExpression(String filterExpression) {
        this.filterExpression = filterExpression;
    }

    public Path getTrustStorePath() {
        return trustStorePath;
    }

    public void setTrustStorePath(Path trustStorePath) {
        this.trustStorePath = trustStorePath;
    }

    public String getTrustStorePassword() {
        return trustStorePassword;
    }

    public void setTrustStorePassword(String trustStorePassword) {
        this.trustStorePassword = trustStorePassword;
    }

    public boolean isUseOid() {
        return useOid;
    }

    public void setUseOid(boolean useOid) {
        this.useOid = useOid;
    }

    public Map<String, String> toAttributes() {
        final HashMap<String, String> attrs = new HashMap<>();
        attrs.put(FILTER_EXPRESSION, filterExpression);
        attrs.put(APPLICATION_DOMAIN_NAME, applicationDomainName);
        attrs.put(TRUST_STORE_PATH, trustStorePath.toAbsolutePath().toString());
        attrs.put(MAX_SEGMENTS, "" + maximumSegments);
        attrs.put(START_SEGMENTS, "" + startSegments);
        attrs.put(USE_OID, "" + useOid);

        for (int i = 0; i < roles.length; i++) {
            attrs.put(ROLE + i, roles[i]);
        }
        attrs.put(ROLE_COUNT, "" + roles.length);
        return attrs;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        CertificateConfig that = (CertificateConfig) o;
        return useOid == that.useOid && Objects.equals(applicationDomainName, that.applicationDomainName) && Arrays.equals(roles, that.roles) && Objects.equals(maximumSegments, that.maximumSegments) && Objects.equals(startSegments, that.startSegments) && Objects.equals(filterExpression, that.filterExpression) && Objects.equals(trustStorePath, that.trustStorePath) && Objects.equals(trustStorePassword, that.trustStorePassword);
    }

    @Override
    public int hashCode() {
        int result = Objects.hash(applicationDomainName, maximumSegments, startSegments, filterExpression, trustStorePath, trustStorePassword, useOid);
        result = 31 * result + Arrays.hashCode(roles);
        return result;
    }

    @Override
    public String toString() {
        return "CertificateConfig{" +
                "applicationDomainName='" + applicationDomainName + '\'' +
                ", roles=" + Arrays.toString(roles) +
                ", maximumSegments=" + maximumSegments +
                ", startSegments=" + startSegments +
                ", filterExpression='" + filterExpression + '\'' +
                ", trustStorePath=" + trustStorePath +
                ", trustStorePassword='" + trustStorePassword + '\'' +
                ", useOid=" + useOid +
                '}';
    }
}
