/*
 * 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.
 */

import difference from 'lodash/difference';
import capitalize from 'lodash/capitalize';
import {REMOVE_CLUSTER_ITEMS_CONFIRMED} from './actionTypes';

export const LOAD_LIST = Symbol('LOAD_LIST');
export const ADD_CLUSTER = Symbol('ADD_CLUSTER');
export const ADD_CLUSTERS = Symbol('ADD_CLUSTERS');
export const REMOVE_CLUSTERS = Symbol('REMOVE_CLUSTERS');
export const UPDATE_CLUSTER = Symbol('UPDATE_CLUSTER');
export const UPSERT_CLUSTERS = Symbol('UPSERT_CLUSTERS');
export const ADD_CACHE = Symbol('ADD_CACHE');
export const UPDATE_CACHE = Symbol('UPDATE_CACHE');
export const UPSERT_CACHES = Symbol('UPSERT_CACHES');
export const REMOVE_CACHE = Symbol('REMOVE_CACHE');

const defaults = {clusters: new Map(), caches: new Map(), spaces: new Map()};

const mapByID = (items) => {
    return Array.isArray(items) ? new Map(items.map((item) => [item._id, item])) : new Map(items);
};

export const reducer = (state = defaults, action) => {
    switch (action.type) {
        case LOAD_LIST: {
            return {
                clusters: mapByID(action.list.clusters),
                domains: mapByID(action.list.domains),
                caches: mapByID(action.list.caches),
                spaces: mapByID(action.list.spaces),
                plugins: mapByID(action.list.plugins)
            };
        }

        case ADD_CLUSTER: {
            return Object.assign({}, state, {
                clusters: new Map([...state.clusters.entries(), [action.cluster._id, action.cluster]])
            });
        }

        case ADD_CLUSTERS: {
            return Object.assign({}, state, {
                clusters: new Map([...state.clusters.entries(), ...action.clusters.map((c) => [c._id, c])])
            });
        }

        case REMOVE_CLUSTERS: {
            return Object.assign({}, state, {
                clusters: new Map([...state.clusters.entries()].filter(([id, value]) => !action.clusterIDs.includes(id)))
            });
        }

        case UPDATE_CLUSTER: {
            const id = action._id || action.cluster._id;
            return Object.assign({}, state, {
                // clusters: new Map(state.clusters).set(id, Object.assign({}, state.clusters.get(id), action.cluster))
                clusters: new Map(Array.from(state.clusters.entries()).map(([_id, cluster]) => {
                    return _id === id
                        ? [action.cluster._id || _id, Object.assign({}, cluster, action.cluster)]
                        : [_id, cluster];
                }))
            });
        }

        case UPSERT_CLUSTERS: {
            return action.clusters.reduce((state, cluster) => reducer(state, {
                type: state.clusters.has(cluster._id) ? UPDATE_CLUSTER : ADD_CLUSTER,
                cluster
            }), state);
        }

        case ADD_CACHE: {
            return Object.assign({}, state, {
                caches: new Map([...state.caches.entries(), [action.cache._id, action.cache]])
            });
        }

        case UPDATE_CACHE: {
            const id = action.cache._id;

            return Object.assign({}, state, {
                caches: new Map(state.caches).set(id, Object.assign({}, state.caches.get(id), action.cache))
            });
        }

        case UPSERT_CACHES: {
            return action.caches.reduce((state, cache) => reducer(state, {
                type: state.caches.has(cache._id) ? UPDATE_CACHE : ADD_CACHE,
                cache
            }), state);
        }

        case REMOVE_CACHE:
            return state;

        default:
            return state;
    }
};


export const RECEIVE_CLUSTER_EDIT = Symbol('RECEIVE_CLUSTER_EDIT');
export const RECEIVE_CACHE_EDIT = Symbol('RECEIVE_CACHE_EDIT');
export const RECEIVE_IGFSS_EDIT = Symbol('RECEIVE_IGFSS_EDIT');
export const RECEIVE_IGFS_EDIT = Symbol('RECEIVE_IGFS_EDIT');
export const RECEIVE_MODELS_EDIT = Symbol('RECEIVE_MODELS_EDIT');
export const RECEIVE_MODEL_EDIT = Symbol('RECEIVE_MODEL_EDIT');

export const editReducer = (state = {originalCluster: null}, action) => {
    switch (action.type) {
        case RECEIVE_CLUSTER_EDIT:
            return {
                ...state,
                originalCluster: action.cluster
            };

        case RECEIVE_CACHE_EDIT: {
            return {
                ...state,
                originalCache: action.cache
            };
        }

        case RECEIVE_IGFSS_EDIT:
            return {
                ...state,
                originalIGFSs: action.igfss
            };

        case RECEIVE_IGFS_EDIT: {
            return {
                ...state,
                originalIGFS: action.igfs
            };
        }

        case RECEIVE_MODELS_EDIT:
            return {
                ...state,
                originalModels: action.models
            };

        case RECEIVE_MODEL_EDIT: {
            return {
                ...state,
                originalModel: action.model
            };
        }

        default:
            return state;
    }
};

export const SHOW_CONFIG_LOADING = Symbol('SHOW_CONFIG_LOADING');
export const HIDE_CONFIG_LOADING = Symbol('HIDE_CONFIG_LOADING');
const loadingDefaults = {isLoading: false, loadingText: 'Loading...'};

export const loadingReducer = (state = loadingDefaults, action) => {
    switch (action.type) {
        case SHOW_CONFIG_LOADING:
            return {...state, isLoading: true, loadingText: action.loadingText};

        case HIDE_CONFIG_LOADING:
            return {...state, isLoading: false};

        default:
            return state;
    }
};

export const setStoreReducerFactory = (actionTypes) => (state = new Set(), action = {}) => {
    switch (action.type) {
        case actionTypes.SET:
            return new Set(action.items.map((i) => i._id));

        case actionTypes.RESET:
            return new Set();

        case actionTypes.UPSERT:
            return action.items.reduce((acc, item) => {acc.add(item._id); return acc;}, new Set(state));

        case actionTypes.REMOVE:
            return action.items.reduce((acc, item) => {acc.delete(item); return acc;}, new Set(state));

        default:
            return state;
    }
};

export const mapStoreReducerFactory = (actionTypes) => (state = new Map(), action = {}) => {
    switch (action.type) {
        case actionTypes.SET:
            return new Map(action.items.map((i) => [i._id, i]));

        case actionTypes.RESET:
            return new Map();

        case actionTypes.UPSERT:
            if (!action.items.length)
                return state;

            return action.items.reduce((acc, item) => {acc.set(item._id, item); return acc;}, new Map(state));

        case actionTypes.REMOVE:
            if (!action.ids.length)
                return state;

            return action.ids.reduce((acc, id) => {acc.delete(id); return acc;}, new Map(state));

        default:
            return state;
    }
};

export const mapCacheReducerFactory = (actionTypes) => {
    const mapStoreReducer = mapStoreReducerFactory(actionTypes);

    return (state = {value: mapStoreReducer(), pristine: true}, action) => {
        switch (action.type) {
            case actionTypes.SET:
            case actionTypes.REMOVE:
            case actionTypes.UPSERT:
                return {
                    value: mapStoreReducer(state.value, action),
                    pristine: false
                };

            case actionTypes.RESET:
                return {
                    value: mapStoreReducer(state.value, action),
                    pristine: true
                };

            default:
                return state;
        }
    };
};

export const basicCachesActionTypes = {
    SET: 'SET_BASIC_CACHES',
    RESET: 'RESET_BASIC_CACHES',
    LOAD: 'LOAD_BASIC_CACHES',
    UPSERT: 'UPSERT_BASIC_CACHES',
    REMOVE: 'REMOVE_BASIC_CACHES'
};

export const mapStoreActionTypesFactory = (NAME) => ({
    SET: `SET_${NAME}`,
    RESET: `RESET_${NAME}`,
    UPSERT: `UPSERT_${NAME}`,
    REMOVE: `REMOVE_${NAME}`
});

export const clustersActionTypes = mapStoreActionTypesFactory('CLUSTERS');
export const shortClustersActionTypes = mapStoreActionTypesFactory('SHORT_CLUSTERS');
export const cachesActionTypes = mapStoreActionTypesFactory('CACHES');
export const shortCachesActionTypes = mapStoreActionTypesFactory('SHORT_CACHES');
export const modelsActionTypes = mapStoreActionTypesFactory('MODELS');
export const shortModelsActionTypes = mapStoreActionTypesFactory('SHORT_MODELS');
export const igfssActionTypes = mapStoreActionTypesFactory('IGFSS');
export const shortIGFSsActionTypes = mapStoreActionTypesFactory('SHORT_IGFSS');

export const itemsEditReducerFactory = (actionTypes) => {
    const setStoreReducer = setStoreReducerFactory(actionTypes);
    const mapStoreReducer = mapStoreReducerFactory(actionTypes);

    return (state = {ids: setStoreReducer(), changedItems: mapStoreReducer()}, action) => {
        switch (action.type) {
            case actionTypes.SET:
                return action.state;

            case actionTypes.LOAD:
                return {
                    ...state,
                    ids: setStoreReducer(state.ids, {...action, type: actionTypes.UPSERT})
                };

            case actionTypes.RESET:
            case actionTypes.UPSERT:
                return {
                    ids: setStoreReducer(state.ids, action),
                    changedItems: mapStoreReducer(state.changedItems, action)
                };

            case actionTypes.REMOVE:
                return {
                    ids: setStoreReducer(state.ids, {type: action.type, items: action.ids}),
                    changedItems: mapStoreReducer(state.changedItems, action)
                };

            default:
                return state;
        }
    };
};

export const editReducer2 = (state = editReducer2.getDefaults(), action) => {
    switch (action.type) {
        case 'SET_EDIT':
            return action.state;

        case 'EDIT_CLUSTER': {
            return {
                ...state,
                changes: {
                    ...['caches', 'models', 'igfss'].reduce((a, t) => ({
                        ...a,
                        [t]: {
                            ids: action.cluster ? action.cluster[t] || [] : [],
                            changedItems: []
                        }
                    }), state.changes),
                    cluster: action.cluster
                }
            };
        }

        case 'RESET_EDIT_CHANGES': {
            return {
                ...state,
                changes: {
                    ...['caches', 'models', 'igfss'].reduce((a, t) => ({
                        ...a,
                        [t]: {
                            ids: state.changes.cluster ? state.changes.cluster[t] || [] : [],
                            changedItems: []
                        }
                    }), state.changes),
                    cluster: {...state.changes.cluster}
                }
            };
        }

        case 'UPSERT_CLUSTER': {
            return {
                ...state,
                changes: {
                    ...state.changes,
                    cluster: action.cluster
                }
            };
        }

        case 'UPSERT_CLUSTER_ITEM': {
            const {itemType, item} = action;
            return {
                ...state,
                changes: {
                    ...state.changes,
                    [itemType]: {
                        ids: state.changes[itemType].ids.filter((_id) => _id !== item._id).concat(item._id),
                        changedItems: state.changes[itemType].changedItems.filter(({_id}) => _id !== item._id).concat(item)
                    }
                }
            };
        }

        case REMOVE_CLUSTER_ITEMS_CONFIRMED: {
            const {itemType, itemIDs} = action;

            return {
                ...state,
                changes: {
                    ...state.changes,
                    [itemType]: {
                        ids: state.changes[itemType].ids.filter((_id) => !itemIDs.includes(_id)),
                        changedItems: state.changes[itemType].changedItems.filter(({_id}) => !itemIDs.includes(_id))
                    }
                }
            };
        }

        default: return state;
    }
};

editReducer2.getDefaults = () => ({
    changes: ['caches', 'models', 'igfss'].reduce((a, t) => ({...a, [t]: {ids: [], changedItems: []}}), {cluster: null})
});

export const refsReducer = (refs) => (state, action) => {
    switch (action.type) {
        case 'ADVANCED_SAVE_COMPLETE_CONFIGURATION': {
            const newCluster = action.changedItems.cluster;
            const oldCluster = state.clusters.get(newCluster._id) || {};
            const val = Object.keys(refs).reduce((state, ref) => {
                if (!state || !state[refs[ref].store].size)
                    return state;

                const addedSources = new Set(difference(newCluster[ref], oldCluster[ref] || []));
                const removedSources = new Set(difference(oldCluster[ref] || [], newCluster[ref]));
                const changedSources = new Map(action.changedItems[ref].map((m) => [m._id, m]));

                const targets = new Map();

                const maybeTarget = (id) => {
                    if (!targets.has(id))
                        targets.set(id, {[refs[ref].at]: {add: new Set(), remove: new Set()}});

                    return targets.get(id);
                };

                [...state[refs[ref].store].values()].forEach((target) => {
                    target[refs[ref].at]
                    .filter((sourceID) => removedSources.has(sourceID))
                    .forEach((sourceID) => maybeTarget(target._id)[refs[ref].at].remove.add(sourceID));
                });

                [...addedSources.values()].forEach((sourceID) => {
                    (changedSources.get(sourceID)[refs[ref].store] || []).forEach((targetID) => {
                        maybeTarget(targetID)[refs[ref].at].add.add(sourceID);
                    });
                });

                action.changedItems[ref].filter((s) => !addedSources.has(s._id)).forEach((source) => {
                    const newSource = source;
                    const oldSource = state[ref].get(source._id);
                    const addedTargets = difference(newSource[refs[ref].store], oldSource[refs[ref].store]);
                    const removedCaches = difference(oldSource[refs[ref].store], newSource[refs[ref].store]);
                    addedTargets.forEach((targetID) => {
                        maybeTarget(targetID)[refs[ref].at].add.add(source._id);
                    });
                    removedCaches.forEach((targetID) => {
                        maybeTarget(targetID)[refs[ref].at].remove.add(source._id);
                    });
                });
                const result = [...targets.entries()]
                    .filter(([targetID]) => state[refs[ref].store].has(targetID))
                    .map(([targetID, changes]) => {
                        const target = state[refs[ref].store].get(targetID);
                        return [
                            targetID,
                            {
                                ...target,
                                [refs[ref].at]: target[refs[ref].at]
                                    .filter((sourceID) => !changes[refs[ref].at].remove.has(sourceID))
                                    .concat([...changes[refs[ref].at].add.values()])
                            }
                        ];
                    });

                return result.length
                    ? {
                        ...state,
                        [refs[ref].store]: new Map([...state[refs[ref].store].entries()].concat(result))
                    }
                    : state;
            }, state);

            return val;
        }

        default:
            return state;
    }
};

export const shortObjectsReducer = (state, action) => {
    switch (action.type) {
        case REMOVE_CLUSTER_ITEMS_CONFIRMED: {
            const {itemType, itemIDs} = action;

            const target = 'short' + capitalize(itemType);

            const oldItems = state[target];

            const newItems = {
                value: itemIDs.reduce((acc, id) => {acc.delete(id); return acc;}, oldItems.value),
                pristine: oldItems.pristine
            };

            return {
                ...state,
                [target]: newItems
            };
        }

        default:
            return state;
    }
};
