package com.aip.gateway.api.aip.manager;

import com.aip.gateway.api.aip.AuthDelegateImpl;
import com.microsoft.informationprotection.Identity;
import com.microsoft.informationprotection.Label;
import com.microsoft.informationprotection.MIP;
import com.microsoft.informationprotection.MipContext;
import com.microsoft.informationprotection.policy.IPolicyEngine;
import com.microsoft.informationprotection.policy.IPolicyProfile;
import com.microsoft.informationprotection.policy.PolicyEngineSettings;
import com.microsoft.informationprotection.policy.PolicyProfileSettings;
import lombok.extern.slf4j.Slf4j;

import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;

@Slf4j
public class PolicyManager extends AbstractManager {
    private IPolicyProfile _profile = null;
    private IPolicyEngine _engine = null;


    @Override
    public void dispose() {
        dispose(true);
    }
    void dispose(boolean disposing) {
        synchronized(this) {
            if (_profile != null && _engine != null) {
                //_profile.UnloadEngineAsync(_engine.Settings.Id).Wait();
                //_profile.dispose();
                //_engine.dispose();

            }
            _engine = null;
            _profile = null;
        }
    }
    @Override
    public boolean createProfile(MipContext mipContext) {
        try {
            PolicyProfileSettings profileSettings = new PolicyProfileSettings(mipContext,
                    com.microsoft.informationprotection.CacheStorageType.ON_DISK_ENCRYPTED);
            Future<IPolicyProfile> policyProfile = MIP.loadPolicyProfileAsync(profileSettings);
            _profile = policyProfile.get();
        }
        catch(InterruptedException ie) {
            setError(1, "PolicyManager::createProfile InterruptedException Exception.", ie.getMessage());
            return false;
        }
        catch(ExecutionException eex) {
            setError(2, "PolicyManager::createProfile ExecutionException Exception.", eex.getMessage());
            return false;
        }
        catch (Exception e) {
            setError(3, "PolicyManager::createProfile Exception.", e.getMessage());
            return false;
        }
        return _profile != null;
    }

    @Override
    public boolean createEngine(Identity identity, AuthDelegateImpl authDelegate) {
        try {
            authDelegate.resetError();
            PolicyEngineSettings engineSettings = new PolicyEngineSettings(identity.getEmail(), authDelegate, "", "en-US");

            engineSettings.setIdentity(identity);

            // Add the engine and get the result.
            Future<IPolicyEngine> egineFuture = _profile.addEngineAsync(engineSettings);
            _engine = egineFuture.get();
        }
        catch(InterruptedException ie) {
            setError(1, "FileManager::createEngine InterruptedException Exception.", ie.getMessage());
            return false;
        }
        catch(ExecutionException eex) {
            setError(2, "FileManager::createEngine ExecutionException Exception.", eex.getMessage());
            return false;
        }
        catch (Exception e) {
            setError(3, "FileManager::createEngine Exception.", e.getMessage());
            return false;
        }
        return _engine != null;
    }

    public List<Label> listSensitivityLabels() {
        // 사용자 주체의 경우 이는 사용자별로 다릅니다.
        // 서비스 주체의 경우 이는 서비스별로 또는 전역적일 수 있습니다.
        return _engine.getSensitivityLabels();
    }
}
