/*
 * 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;
    @Input() on: boolean = false; // Override the parent class attribute
    @Output() mastershipEvent = new EventEmitter<string>();
    public onosInstances: Array<Instance>;
    public 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.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');

    }
}
