/*
 * Copyright 2018-present Open Networking Foundation
 *
 * 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.
 */
import {
    Component,
    Input,
    Output,
    EventEmitter
} from '@angular/core';
import { animate, state, style, transition, trigger } from '@angular/animations';
import {
    LogService,
    LoadingService,
    FnService,
    PanelBaseImpl,
    IconService,
    SvgUtilService, LionService
} from 'gui2-fw-lib';

/**
 * A model of instance information that drives each panel
 */
export interface Instance {
    id: string;
    ip: string;
    online: boolean;
    ready: boolean;
    switches: number;
    uiAttached: boolean;
}

/**
 * ONOS GUI -- Topology Instances Panel.
 * Displays ONOS instances. The onosInstances Array gets updated by topology.service
 * whenever a topo2AllInstances update arrives back on the WebSocket
 *
 * This emits a mastership event when the user clicks on an instance, to
 * see the devices that it has mastership of.
 */
@Component({
    selector: 'onos-instance',
    templateUrl: './instance.component.html',
    styleUrls: [
        './instance.component.css', './instance.theme.css',
        '../../topology.common.css',
        '../../../../fw/widget/panel.css', '../../../../fw/widget/panel-theme.css'
    ],
    animations: [
        trigger('instancePanelState', [
            state('true', style({
                transform: 'translateX(0%)',
                opacity: '1.0'
            })),
            state('false', style({
                transform: 'translateX(-100%)',
                opacity: '0.0'
            })),
            transition('0 => 1', animate('100ms ease-in')),
            transition('1 => 0', animate('100ms ease-out'))
        ])
    ]
})
export class InstanceComponent extends PanelBaseImpl {
    @Input() divTopPx: number = 100;
    @Output() mastershipEvent = new EventEmitter<string>();
    public onosInstances: Array<Instance>;
    protected mastership: string;
    lionFn; // Function

    constructor(
        protected fs: FnService,
        protected log: LogService,
        protected ls: LoadingService,
        protected is: IconService,
        protected sus: SvgUtilService,
        private lion: LionService
    ) {
        super(fs, ls, log);
        this.onosInstances = <Array<Instance>>[];

        if (this.lion.ubercache.length === 0) {
            this.lionFn = this.dummyLion;
            this.lion.loadCbs.set('topo-inst', () => this.doLion());
        } else {
            this.doLion();
        }
        this.on = true;
        this.log.debug('InstanceComponent constructed');
    }

    /**
     * Get a colour for the banner of the nth panel
     * @param idx The index of the panel (0-6)
     */
    panelColour(idx: number): string {
        return this.sus.cat7().getColor(idx, false, '');
    }

    /**
     * Toggle the display of mastership
     * If the same instance is clicked a second time then cancel display of mastership
     * @param instId The instance to display mastership for
     */
    chooseMastership(instId: string): void {
        if (this.mastership === instId) {
            this.mastership = '';
        } else {
            this.mastership = instId;
        }
        this.mastershipEvent.emit(this.mastership);
        this.log.debug('Instance', this.mastership, 'chosen on GUI');
    }

    /**
     * Read the LION bundle for Details panel and set up the lionFn
     */
    doLion() {
        this.lionFn = this.lion.bundle('core.view.Topo');

    }
}
