/*
 * Copyright (c) 2022.
 * Author Peter Placzek (tada5hi)
 * For the full copyright and license information,
 * view the LICENSE file that was distributed with this source code.
 */

import {ActionTree, GetterTree, MutationTree} from "vuex";
import {RootState} from "~/store/index";
import {SecurityKeyPair} from "~/modules/security";
import {editContact} from "~/domains/contact/api";
import Vue from "vue";

// --------------------------------------------------------------------

export interface ChatState {
    contactSelfKeyPairs: Record<string, SecurityKeyPair>,
    contactRelatedKeys: Record<string, string>,
    symmetricKeys: Record<string, string>
}

export const state = () : ChatState => ({
    contactSelfKeyPairs: {},
    contactRelatedKeys: {},
    symmetricKeys: {}
});

export const getters : GetterTree<ChatState, RootState> = {
    isContactCommunicationEncrypted: (state) => (contactId: string) => {
        return state.contactSelfKeyPairs.hasOwnProperty(contactId) && state.contactRelatedKeys.hasOwnProperty(contactId);
    },
    contactSelfKeyPair: (state) => (contactId: string) => {
        return state.contactSelfKeyPairs[contactId];
    },
    contactRelatedKey: (state) => (contactId: string) => {
        return state.contactRelatedKeys.hasOwnProperty(contactId) ? state.contactRelatedKeys[contactId] : undefined;
    },


    isRoomCommunicationEncrypted: (state) => (roomId: string) => {
        return state.symmetricKeys.hasOwnProperty(roomId);
    },
    roomSymmetricKey: (state) => (roomId: string) => {
        return state.symmetricKeys[roomId];
    }
};

export const actions : ActionTree<ChatState, RootState> = {
    async setContactSelfKeyPair({commit, state}, {contactId, keyPair}) : Promise<void> {
        commit('setContactSelfKeyPair', {contactId, keyPair});
    },

    async createContactSelfKeyPair({commit, state}, contactId: string) : Promise<SecurityKeyPair> {
        const keyPair = await this.$security.createKeyPair();
        await this.$security.saveContactSelfKeyPair(contactId, keyPair);
        commit('setContactSelfKeyPair', {contactId, keyPair});

        await editContact(contactId, {
            key: keyPair.publicKey
        });

        return keyPair;
    },

    //-------------------------------------------------------

    async setContactRelatedKey({commit, state, rootGetters}, {contactId, key}) : Promise<void> {
        commit('setContactRelatedKey', {contactId, key});
    },

    async saveContactRelatedKey({commit, state, rootGetters}, {contactId, key}) {
        commit('setContactRelatedKey', {contactId, key: key});

        await this.$security.saveContactRelatedKey(contactId, key);
    },

    //-------------------------------------------------------

    setRoomSymmetricKey({commit}, {roomId, key}) {
        commit('setSymmetricKey', {roomId, key});
    }
};

export const mutations : MutationTree<ChatState> = {
    // --------------------------------------------------------------------

    setContactSelfKeyPair(state, {contactId, keyPair}) {
        Vue.set(state.contactSelfKeyPairs, contactId, keyPair);
    },
    setContactRelatedKey(state, {contactId, key}) {
        Vue.set(state.contactRelatedKeys, contactId, key);
    },

    // --------------------------------------------------------------------

    setRoomSymmetricKey(state, {roomId, key}) {
        Vue.set(state.symmetricKeys, roomId, key);
    }
};

// --------------------------------------------------------------------

export default {
    namespaced: true,
    state,
    getters,
    actions,
    mutations
}
