/*-
 * ~~~~~~licensing~~~~~~
 * resource-based-storage
 * ==========
 * Copyright (C) 2020 - 2025 EmDev LLC
 * ==========
 * You may not use this file except in accordance with the License Terms of the Copyright
 * Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
 * rights to the Software and any copies are the property of the Copyright Holder. Unless
 * it is explicitly allowed the Copyright Holder, the User is prohibited from using the
 * Software for commercial purposes to provide services to third parties.
 * 
 * The Copyright Holder hereby declares that the Software is provided on an "AS IS".
 * Under no circumstances does the Copyright Holder guarantee or promise that the
 * Software provided by him will be suitable or not suitable for the specific purposes
 * of the User, that the Software will meet all commercial and personal subjective
 * expectations of the User, that the Software will work properly, without technical
 * errors, quickly and uninterruptedly.
 * 
 * Under no circumstances shall the Copyright Holder or its Affiliates is not liable
 * to the User for any direct or indirect losses of the User, his expenses or actual
 * damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
 * or damage to data, property, etc.
 * ~~~~~~/licensing~~~~~~
 */
package ru.entaxy.platform.integration.applications.storage.resource.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import ru.entaxy.platform.integration.applications.EntaxyApplicationProject;
import ru.entaxy.platform.integration.applications.exceptions.ProjectException;
import ru.entaxy.platform.integration.applications.exceptions.StorageException;
import ru.entaxy.platform.integration.applications.storage.resource.impl.project.ProjectComponent;

public class ProjectStorageComponent extends AbstractResourceComponent<ProjectStorageData> {

    private static final Logger LOG = LoggerFactory.getLogger(ProjectStorageComponent.class);

    final protected Map<String, ProjectComponent> projectCache = new HashMap<>();

    protected Object projectCacheLock = new Object();

    /*
    public ProjectStorageComponent(EntaxyResourceService entaxyResourceService, String parentRootUrl) {
        super(entaxyResourceService);
        this.rootResourceFolderUrl = parentRootUrl.concat("/").concat("projects");
    }
    */

    public ProjectStorageComponent(ResourceContext parentResourceContext) {
        super(parentResourceContext.subcontext("projects"));
    }

    @Override
    protected Class<ProjectStorageData> getDataObjectClass() {
        return ProjectStorageData.class;
    }

    @Override
    protected String getRootResourceName() {
        return ".projects";
    }

    @Override
    protected ProjectStorageData createDataObject() {
        return new ProjectStorageData();
    }

    @Override
    public String getComponentKey() {
        return "projects";
    }

    @Override
    public void init() {
        super.init();
        initializeProjectCache();
    }

    protected void initializeProjectCache() {
        synchronized (projectCacheLock) {
            if (dataObject.projects == null)
                return;
            for (String projectName : dataObject.projects) {
                ProjectComponent comp = loadProject(projectName);
                if (comp != null)
                    projectCache.put(comp.getName(), comp);
            }
        }
    }

    protected ProjectComponent loadProject(String projectName) {
        try {
            ProjectComponent component =
                    new ProjectComponent(resourceContext, projectName);
            component.init();
            return component;
        } catch (Exception e) {
            LOG.error("Error creating project [" + projectName + "]", e);
        }
        return null;
    }

    public boolean projectExists(String projectName) {
        return dataObject.hasProject(projectName);
    }

    public List<ProjectComponent> getProjects() {
        return new ArrayList<>(projectCache.values());
    }

    public ProjectComponent getProject(String projectName) {
        return projectCache.get(projectName);
    }

    public void addProject(EntaxyApplicationProject project) throws ProjectException, StorageException {
        // TODO Auto-generated method stub

    }

    public void removeProject(EntaxyApplicationProject project)
            throws ProjectException, StorageException {
        synchronized (projectCacheLock) {
            String projectName = project.getName();
            ProjectComponent comp = projectCache.get(projectName);
            if (comp == null)
                return;
            comp.delete();
            projectCache.remove(projectName);
            dataObject.removeProject(projectName);
            try {
                updateRootResource();
            } catch (Exception e) {
                LOG.error("Error removing project [" + projectName + "]", e);
            }
        }
    }

    public ProjectComponent createProject(String projectName)
            throws ProjectException, StorageException {
        try {
            ProjectComponent component =
                    new ProjectComponent(resourceContext, projectName);
            component.init();
            synchronized (projectCacheLock) {
                dataObject.addProject(component.getName());
                updateRootResource();
                projectCache.put(component.getName(), component);
            }
            return component;
        } catch (Exception e) {
            LOG.error("Error creating project [" + projectName + "]", e);
        }
        return null;
    }


}
