/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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.netbeans.modules.project.ui;

import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import org.netbeans.api.project.Project;
import org.netbeans.api.project.ui.OpenProjects;
import org.netbeans.api.project.ui.ProjectGroup;
import org.netbeans.api.project.ui.ProjectGroupChangeListener;
import org.netbeans.insane.live.CancelException;
import org.netbeans.modules.project.uiapi.OpenProjectsTrampoline;
import org.netbeans.modules.project.uiapi.ProjectOpenedTrampoline;
import org.netbeans.spi.project.ui.ProjectOpenedHook;
import org.openide.util.lookup.ServiceProvider;

/**
 *
 * @author Tomas Zezula
 */
@ServiceProvider(service = OpenProjectsTrampoline.class)
public final class TestTrampoline implements OpenProjectsTrampoline {

    private final PropertyChangeSupport support = new PropertyChangeSupport(this);
    private final ReadWriteLock rwLock = new ReentrantReadWriteLock();
    private final Set<Project> opened = new HashSet<>();
    private volatile Project mainProject;

    @Override
    public Project[] getOpenProjectsAPI() {
        rwLock.readLock().lock();
        try {
            return opened.toArray(new Project[opened.size()]);
        } finally {
            rwLock.readLock().unlock();
        }
    }

    @Override
    public void openAPI(Project[] projects, boolean openRequiredProjects, boolean showProgress) {
        final Set<Project> justOpened = new HashSet<>();
        rwLock.writeLock().lock();
        try {
            for (Project p : projects) {
                if (opened.add(p)) {
                    justOpened.add(p);
                }
            }
        } finally {
           rwLock.writeLock().unlock();
        }
        for (Project p : justOpened) {
            for (ProjectOpenedHook hook : p.getLookup().lookupAll(ProjectOpenedHook.class)) {
                ProjectOpenedTrampoline.DEFAULT.projectOpened(hook);
            }
        }
        if (!justOpened.isEmpty()) {
            support.firePropertyChange(OpenProjects.PROPERTY_OPEN_PROJECTS, null, null);
        }
    }

    @Override
    public void closeAPI(Project[] projects) {
        final Set<Project> justClosed = new HashSet<>();
        rwLock.writeLock().lock();
        try {
            for (Project p : projects) {
                if (opened.remove(p)) {
                    justClosed.add(p);
                }
            }
        } finally {
            rwLock.writeLock().unlock();
        }
        for (Project p : justClosed) {
            for (ProjectOpenedHook hook : p.getLookup().lookupAll(ProjectOpenedHook.class)) {
                ProjectOpenedTrampoline.DEFAULT.projectClosed(hook);
            }
        }
        if (!justClosed.isEmpty()) {
            support.firePropertyChange(OpenProjects.PROPERTY_OPEN_PROJECTS, null, null);
        }
    }

    @Override
    public void addPropertyChangeListenerAPI(PropertyChangeListener listener, Object source) {
        this.support.addPropertyChangeListener(listener);
    }

    @Override
    public void removePropertyChangeListenerAPI(PropertyChangeListener listener) {
        this.support.removePropertyChangeListener(listener);
    }

    @Override
    public Future<Project[]> openProjectsAPI() {
        return new F();
    }


    @Override
    public Project getMainProject() {
        return mainProject;
    }

    @Override
    public void setMainProject(Project project) {
        mainProject = project;
        support.firePropertyChange(OpenProjects.PROPERTY_MAIN_PROJECT, null, null);
    }

    @Override
    public ProjectGroup getActiveProjectGroupAPI() {
        return null;
    }

    @Override
    public void addProjectGroupChangeListenerAPI(ProjectGroupChangeListener listener) {
    }

    @Override
    public void removeProjectGroupChangeListenerAPI(ProjectGroupChangeListener listener) {
    }

    private final class F implements Future<Project[]> {

        private volatile Project[] res;
        private volatile boolean canceled;

        @Override
        public boolean cancel(boolean mayInterruptIfRunning) {
            return canceled = true;
        }

        @Override
        public boolean isCancelled() {
            return canceled;
        }

        @Override
        public boolean isDone() {
            return canceled || res != null;
        }

        @Override
        public Project[] get() throws InterruptedException, ExecutionException {
            if (canceled) {
                throw new CancelException();
            }
            if (res != null) {
                return res;
            }
            return res = getOpenProjectsAPI();
        }

        @Override
        public Project[] get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException {
            if (canceled) {
                throw new CancelException();
            }
            if (res != null) {
                return res;
            }
            if (rwLock.readLock().tryLock(timeout, unit)) {
                try {
                    return res = getOpenProjectsAPI();
                }finally {
                    rwLock.readLock().unlock();
                }
            }
            throw new TimeoutException();
        }
    }
}
