/****************************************************************************
* Copyright Avaya Inc., All Rights Reserved.
* THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF Avaya Inc.
* The copyright notice above does not evidence any actual or intended publication of such source code.
* Some third-party source code components may have been modified from their original versions by Avaya Inc.
* The modifications are Copyright Avaya Inc., All Rights Reserved.
* Avaya Confidential & Restricted. May not be distributed further without written permission of
* the Avaya owner.
****************************************************************************/
package com.avaya.zephyr.services.sample_services.Authorization.TaskRepository.holder;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicLong;

import org.apache.commons.lang3.StringUtils;

import com.avaya.zephyr.services.sample_services.Authorization.TaskRepository.json.Task;

/*This is an in-memory storage of tasks.*/
public final class TaskHolder
{
    private static final TaskHolder INSTANCE = new TaskHolder();
    private final List<Task> tasks;
    private final Map<String, List<Task>> userIdToTaskMap;
    private final AtomicLong taskId;

    private TaskHolder()
    {
        tasks = new ArrayList<Task>();
        userIdToTaskMap = new ConcurrentHashMap<String, List<Task>>();
        taskId = new AtomicLong();
        // Dummy task
        final DateFormat df = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss");
        final Date today = new Date();
        addTask(new Task("taskId", "sample@avaya.com", "sample task", "sample description", false,
                df.format(today)));
        // ==========
    }

    public static TaskHolder getInstance()
    {
        return INSTANCE;
    }

    public synchronized List<Task> getAllTasks()
    {
        return new ArrayList<Task>(tasks);
    }

    public List<Task> getTasksByUserId(final String userId)
    {
        if (StringUtils.isEmpty(userId))
        {
            return Collections.emptyList();
        }
        synchronized (this)
        {
            final List<Task> taskList = userIdToTaskMap.get(userId);
            if (taskList == null)
            {
                return Collections.emptyList();
            }
            return new ArrayList<Task>(taskList);
        }
    }

    public void addTask(final Task task)
    {
        if (task == null)
        {
            return;
        }
        synchronized (this)
        {
            tasks.add(task);
            if (userIdToTaskMap.get(task.getUserId()) == null)
            {
                userIdToTaskMap.put(task.getUserId(), new ArrayList<Task>());
            }
            userIdToTaskMap.get(task.getUserId()).add(task);
        }
    }

    public boolean deleteTask(final String userId, final String taskId)
    {
        if (StringUtils.isEmpty(userId) || StringUtils.isEmpty(taskId))
        {
            return false;
        }
        synchronized (this)
        {
            final List<Task> taskList = userIdToTaskMap.get(userId);
            if (taskList == null)
            {
                return false;
            }
            for (final Iterator<Task> iterator = taskList.iterator(); iterator
                    .hasNext();)
            {
                final Task task = iterator.next();
                if (task.getTaskId().equals(taskId))
                {
                    tasks.remove(task);
                    iterator.remove();
                    return true;
                }
            }
        }
        return false;
    }

    public Task updateTask(final Task inputTask)
    {
        if (inputTask == null || StringUtils.isBlank(inputTask.getUserId()) ||
                StringUtils.isBlank(inputTask.getTaskId()))
        {
            return null;
        }
        synchronized (this)
        {
            final List<Task> taskList = userIdToTaskMap.get(inputTask.getUserId());
            if (taskList == null)
            {
                return null;
            }
            for (final Task task : taskList)
            {
                if (task.getTaskId().equals(inputTask.getTaskId()))
                {
                    task.setClosed(inputTask.isClosed());
                    task.setDescription(inputTask.getDescription());
                    task.setTitle(inputTask.getTitle());
                    return task;
                }
            }
        }
        return null;
    }

    public long getNextTaskId()
    {
        return taskId.incrementAndGet();
    }
}
