import { code } from 'dashboard/generated/controlplane';
import * as React from 'react';
import { defaultMemoize } from 'reselect';
import { CoreText } from 'twitch-core-ui';
import { encodeEventStreamKey } from './encodeEventStream';
import twirp = code.justin.tv.eventbus.controlplane;

export function renderStatusOfSubscription (sub: twirp.ISubscription | null) {
  const statusMsg = (() => {
    if (!sub) {
      return 'Disabled';
    }
    switch (sub.status) {
      case twirp.SubscriptionStatus.SUBSCRIPTION_STATUS_DISABLED: {
        return 'Disabled';
      }
      case twirp.SubscriptionStatus.SUBSCRIPTION_STATUS_ENABLED: {
        return 'Enabled';
      }
      case twirp.SubscriptionStatus.SUBSCRIPTION_STATUS_ERROR_CREATE: {
        return 'Create error: ' + sub.message;
      }
      case twirp.SubscriptionStatus.SUBSCRIPTION_STATUS_ERROR_DISABLE: {
        return 'Disable error: ' + sub.message;
      }
      case twirp.SubscriptionStatus.SUBSCRIPTION_STATUS_ERROR_ENABLE: {
        return 'Enable error: ' + sub.message;
      }
      case twirp.SubscriptionStatus.SUBSCRIPTION_STATUS_PENDING_ENABLE: {
        return 'Pending enable';
      }
      case twirp.SubscriptionStatus.SUBSCRIPTION_STATUS_PENDING_DISABLE: {
        return 'Pending disable';
      }
      case twirp.SubscriptionStatus.SUBSCRIPTION_STATUS_PENDING_DELETE: {
        return 'Pending delete';
      }
      case twirp.SubscriptionStatus.SUBSCRIPTION_STATUS_ERROR_DELETE: {
        return 'Error delete: ' + sub.message;
      }
      default: {
        return 'Unknown';
      }
    }
  })();
  return (
    <CoreText>{statusMsg}</CoreText>
  );
}

export function getSubscriptionIfExists(subs: twirp.ISubscription[], eventType: string, environment: string): twirp.ISubscription | null {
    for (const s of subs) {
        if (s.eventType === eventType && s.environment === environment) {
            return s;
        }
    }
    return null;
}

export interface StreamWithSub {
    eventStream: twirp.EventStream;
    subscription?: twirp.ISubscription;
}

// map subscriptions onto event streams using their event type + environment
export function annotatedSubs(eventStreams: twirp.EventStream[], subs: twirp.ISubscription[]): StreamWithSub[] {
    // build a mapping of event stream key => sub object
    const lookup: {[key: string]: twirp.ISubscription} = {};
    for (const sub of subs) {
      lookup[encodeEventStreamKey(sub.eventType || '', sub.environment || '')] = sub;
    }

    // attach any items matching to eventstream
    return eventStreams.map((eventStream) => {
      const subscription = lookup[encodeEventStreamKey(eventStream.eventType || '', eventStream.environment || '')];
      return { eventStream, subscription };
    });
}

interface EnabledDisabled {
  enabled: StreamWithSub[];
  disabled: StreamWithSub[];
}

export type EnabledDisabledSubsSelector = (streams: twirp.EventStream[], subs: twirp.ISubscription[]) => EnabledDisabled;

// Create a selector that separates enabled and disabled subscriptions.
export function newEnabledDisabledSubsSelector(): EnabledDisabledSubsSelector {
  return defaultMemoize((eventStreams: twirp.EventStream[], subs: twirp.ISubscription[]) => {
    const enabled: StreamWithSub[] = [];
    const disabled: StreamWithSub[] = [];

    const annotated = annotatedSubs(eventStreams, subs);
    for (const sws of annotated) {
      if (sws.subscription) {
        enabled.push(sws);
      } else {
        disabled.push(sws);
      }
    }
    return { enabled, disabled };
  });
}
