/*
 * Copyright 2016 Red Hat, Inc. and/or its affiliates
 * and other 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.keycloak.storage;

import org.keycloak.component.ComponentModel;

import org.infinispan.protostream.annotations.ProtoTypeId;

/**
 * Stored configuration of a User Storage provider instance.
 *
 * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
 * @author <a href="mailto:bburke@redhat.com">Bill Burke</a>
 */
@ProtoTypeId(65539) //see org.keycloak.Marshalling
public class UserStorageProviderModel extends CacheableStorageProviderModel {

    public static final String IMPORT_ENABLED = "importEnabled";
    public static final String FULL_SYNC_PERIOD = "fullSyncPeriod";
    public static final String CHANGED_SYNC_PERIOD = "changedSyncPeriod";
    public static final String LAST_SYNC = "lastSync";
    public static final String REMOVE_INVALID_USERS_ENABLED = "removeInvalidUsersEnabled";

    public enum SyncMode {
        FULL, CHANGED;
    }

    public UserStorageProviderModel() {
        setProviderType(UserStorageProvider.class.getName());
    }

    public UserStorageProviderModel(ComponentModel copy) {
        super(copy);
    }

    private transient Integer fullSyncPeriod;
    private transient Integer changedSyncPeriod;
    private transient Boolean importEnabled;
    private transient Boolean removeInvalidUsersEnabled;

    public boolean isImportEnabled() {
        if (importEnabled == null) {
            importEnabled = Boolean.parseBoolean(getConfig().getFirstOrDefault(IMPORT_ENABLED, Boolean.TRUE.toString()));
        }
        return importEnabled;
    }

    public void setImportEnabled(boolean flag) {
        importEnabled = flag;
        getConfig().putSingle(IMPORT_ENABLED, Boolean.toString(flag));
    }


    public int getFullSyncPeriod() {
        if (fullSyncPeriod == null) {
            String val = getConfig().getFirst(FULL_SYNC_PERIOD);
            if (val == null) {
                fullSyncPeriod = -1;
            } else {
                fullSyncPeriod = Integer.valueOf(val);
            }
        }
        return fullSyncPeriod;
    }

    public void setFullSyncPeriod(int fullSyncPeriod) {
        this.fullSyncPeriod = fullSyncPeriod;
        getConfig().putSingle(FULL_SYNC_PERIOD, Integer.toString(fullSyncPeriod));
    }

    public int getChangedSyncPeriod() {
        if (changedSyncPeriod == null) {
            String val = getConfig().getFirst(CHANGED_SYNC_PERIOD);
            if (val == null) {
                changedSyncPeriod = -1;
            } else {
                changedSyncPeriod = Integer.valueOf(val);
            }
        }
        return changedSyncPeriod;
    }

    public void setChangedSyncPeriod(int changedSyncPeriod) {
        this.changedSyncPeriod = changedSyncPeriod;
        getConfig().putSingle(CHANGED_SYNC_PERIOD, Integer.toString(changedSyncPeriod));
    }

    public int getLastSync() {
        return Math.max(getLastSync(SyncMode.FULL), getLastSync(SyncMode.CHANGED));
    }

    public int getLastSync(SyncMode syncMode) {
        String val = getConfig().getFirst(LAST_SYNC + "_" + syncMode.name());
        if (val == null) {
            return 0;
        }
        return Integer.parseInt(val);
    }

    public void setLastSync(int lastSync, SyncMode syncMode) {
        getConfig().putSingle(LAST_SYNC + "_" + syncMode.name(), Integer.toString(lastSync));
    }

    public void setLastSync(int lastSync) {
        setLastSync(lastSync, SyncMode.FULL);
        setLastSync(lastSync, SyncMode.CHANGED);
    }

    public boolean isRemoveInvalidUsersEnabled() {
        if (removeInvalidUsersEnabled == null) {
            String val = getConfig().getFirst(REMOVE_INVALID_USERS_ENABLED);
            if (val == null) {
                removeInvalidUsersEnabled = true;
            } else {
                removeInvalidUsersEnabled = Boolean.valueOf(val);
            }
        }
        return removeInvalidUsersEnabled;
    }
}
