/*
 * 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,
    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 is: IconService,
        protected sus: SvgUtilService,
        private lion: LionService
    ) {
        super(fs, 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');

    }
}
