/*
 * Copyright 2016 SimplifyOps, Inc. (http://simplifyops.com)
 *
 * 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 com.dtolabs.rundeck.server.projects;

import com.dtolabs.rundeck.core.authorization.Authorization;
import com.dtolabs.rundeck.core.common.*;
import com.dtolabs.rundeck.core.utils.IPropertyLookup;
import rundeck.services.ProjectManagerService;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.*;

/**
 * Created by greg on 2/23/15.
 */
public class RundeckProject implements IRundeckProject{
    private ProjectManagerService projectService;
    private IRundeckProjectConfig projectConfig;
    private IProjectInfo info;
    private IProjectNodesFactory nodesFactory;

    public RundeckProject(
            final IRundeckProjectConfig projectConfig,
            final ProjectManagerService projectService
    )
    {
        this.projectConfig=projectConfig;
        this.projectService = projectService;

    }

    public String getName(){
        return projectConfig.getName();
    }

    public String getProperty(final String property) {
        return projectConfig.getProperty(property);
    }

    @Override
    public List<Map<String, Object>> listResourceModelConfigurations() {
        return getProjectNodes().listResourceModelConfigurations();
    }

    @Override
    public INodeSet getNodeSet() throws NodeFileParserException {
        return getProjectNodes().getNodeSet();
    }

    @Override
    public boolean hasProperty(final String key) {
        return projectConfig.hasProperty(key);
    }

    @Override
    public Map<String, String> getProperties() {
        return projectConfig.getProperties();
    }
    @Override
    public Map<String, String> getProjectProperties() {
        return projectConfig.getProjectProperties();
    }

    @Override
    public void mergeProjectProperties(final Properties properties, final Set<String> removePrefixes) {
        projectService.mergeProjectProperties(this, properties, removePrefixes);
    }

    @Override
    public void setProjectProperties(final Properties properties) {
        projectService.setProjectProperties(this, properties);
    }

    @Override
    public boolean existsFileResource(final String path) {
        return projectService.existsProjectFileResource(getName(), path);
    }

    @Override
    public boolean existsDirResource(final String path) {
        return projectService.existsProjectDirResource(getName(), path);
    }

    @Override
    public List<String> listDirPaths(final String path) {
        return projectService.listProjectDirPaths(getName(), path);
    }

    @Override
    public boolean deleteFileResource(final String path) {
        return projectService.deleteProjectFileResource(getName(), path);
    }

    @Override
    public long storeFileResource(final String path, final InputStream input) throws IOException {
        return projectService.writeProjectFileResource(getName(), path, input, new HashMap<String, String>())
                             .getContents()
                             .getContentLength();
    }

    @Override
    public long loadFileResource(final String path, final OutputStream output) throws IOException {
        return projectService.readProjectFileResource(getName(),path,output);
    }

    @Override
    public Date getConfigLastModifiedTime() {
        return projectConfig.getConfigLastModifiedTime();
    }

    public Date getConfigCreatedTime(){
        return projectConfig.getConfigCreatedTime();
    }


    public IProjectNodes getProjectNodes() {
        return getNodesFactory().getNodes(getName());
    }

    @Override
    public String toString() {
        return "RundeckProject{" +
               "config='" + projectConfig + '\'' +
               '}';
    }


    public Authorization getProjectAuthorization() {
        return projectService.getProjectAuthorization(getName());
    }

    public IRundeckProjectConfig getProjectConfig() {
        return projectConfig;
    }

    public void setProjectConfig(IRundeckProjectConfig projectConfig) {
        this.projectConfig = projectConfig;
    }

    @Override
    public IProjectInfo getInfo() {
        return info;
    }

    public void setInfo(IProjectInfo info) {
        this.info = info;
    }

    public IProjectNodesFactory getNodesFactory() {
        return nodesFactory;
    }

    public void setNodesFactory(IProjectNodesFactory nodesFactory) {
        this.nodesFactory = nodesFactory;
    }
}

@@ -1085,16 +1085,22 @@
 private 
+final 
 ProjectM
@@ -1260,35 +1260,97 @@
 ry;%0A
-%0A    public RundeckProject(
+    private final String name;%0A%0A    public RundeckProject(%0A            final String name,
 %0A   
@@ -1468,16 +1468,42 @@
 )%0A    %7B%0A
+        this.name = name;%0A
         
@@ -1520,17 +1520,19 @@
 ctConfig
-=
+ = 
 projectC
@@ -1640,31 +1640,12 @@
 urn 
-projectConfig.getN
+n
 ame
-()
 ;%0A  
@@ -1711,33 +1711,36 @@
 %0A        return 
-p
+getP
 rojectConfig.get
@@ -1727,32 +1727,34 @@
 getProjectConfig
+()
 .getProperty(pro
@@ -2136,33 +2136,36 @@
 %0A        return 
-p
+getP
 rojectConfig.has
@@ -2160,16 +2160,18 @@
 ctConfig
+()
 .hasProp
@@ -2258,33 +2258,36 @@
 %0A        return 
-p
+getP
 rojectConfig.get
@@ -2278,24 +2278,26 @@
 rojectConfig
+()
 .getProperti
@@ -2385,33 +2385,36 @@
 %0A        return 
-p
+getP
 rojectConfig.get
@@ -2405,24 +2405,26 @@
 rojectConfig
+()
 .getProjectP
@@ -3998,33 +3998,36 @@
 %0A        return 
-p
+getP
 rojectConfig.get
@@ -4014,32 +4014,34 @@
 getProjectConfig
+()
 .getConfigLastMo
@@ -4108,33 +4108,36 @@
 %0A        return 
-p
+getP
 rojectConfig.get
@@ -4132,16 +4132,18 @@
 ctConfig
+()
 .getConf
@@ -4608,24 +4608,149 @@
 tConfig() %7B%0A
+        if (null == projectConfig) %7B%0A            this.projectConfig = projectService.loadProjectConfig(this.name);%0A        %7D%0A
         retu

add lazy loading of project config