import { Observable } from "rxjs/Observable";
import { switchMap, tap } from "rxjs/operators";
import "rxjs/add/observable/empty";
import "rxjs/add/observable/of";
import "rxjs/add/operator/do";
import "rxjs/add/operator/switchMap";

declare module "rxjs/Observable" {
    interface Observable<T> {
        ofType(type: string, ...moreTypes: string[]): Observable<T>;
    }
}

function ofType<T>(type: string, ...moreTypes: string[]): (source: Observable<T>) => Observable<T> {
    return source => source;
}

type Actions = Observable<any>;
const actions = Observable.of({});
const empty = Observable.empty() as Observable<never>;

const GET_SOMETHING = "GET_SOMETHING";
const PUT_SOMETHING = "PUT_SOMETHING";
const GetSomething = GET_SOMETHING;
const PutSomething = PUT_SOMETHING;

const patchedGetEffect = actions.ofType("GET_SOMETHING").do(() => {}).switchMap(() => empty);
const patchedPutEffect = actions.ofType("PUT_SOMETHING").do(() => {}).switchMap(() => empty);
                                                                      ~~~~~~~~~                                                             [no-unsafe-switchmap]
const pipedGetEffect = actions.ofType("GET_SOMETHING").pipe(tap(() => {}), switchMap(() => empty));
const pipedPutEffect = actions.ofType("PUT_SOMETHING").pipe(tap(() => {}), switchMap(() => empty));
                                                                           ~~~~~~~~~                                                        [no-unsafe-switchmap]

const patchedMoreGetEffect = actions.ofType("DO_SOMETHING", "GET_SOMETHING").do(() => {}).switchMap(() => empty);
const patchedMorePutEffect = actions.ofType("DO_SOMETHING", "PUT_SOMETHING").do(() => {}).switchMap(() => empty);
                                                                                          ~~~~~~~~~                                         [no-unsafe-switchmap]
const pipedMoreGetEffect = actions.ofType("DO_SOMETHING", "GET_SOMETHING").pipe(tap(() => {}), switchMap(() => empty));
const pipedMorePutEffect = actions.ofType("DO_SOMETHING", "PUT_SOMETHING").pipe(tap(() => {}), switchMap(() => empty));
                                                                                               ~~~~~~~~~                                    [no-unsafe-switchmap]

const patchedGetEpic = (action$: Actions) => action$.ofType("GET_SOMETHING").do(() => {}).switchMap(() => empty);
const patchedPutEpic = (action$: Actions) => action$.ofType("PUT_SOMETHING").do(() => {}).switchMap(() => empty);
                                                                                          ~~~~~~~~~                                         [no-unsafe-switchmap]
const pipedGetEpic = (action$: Actions) => action$.ofType("GET_SOMETHING").pipe(tap(() => {}), switchMap(() => empty));
const pipedPutEpic = (action$: Actions) => action$.ofType("PUT_SOMETHING").pipe(tap(() => {}), switchMap(() => empty));
                                                                                               ~~~~~~~~~                                    [no-unsafe-switchmap]

const patchedMoreGetEpic = (action$: Actions) => action$.ofType("DO_SOMETHING", "GET_SOMETHING").do(() => {}).switchMap(() => empty);
const patchedMorePutEpic = (action$: Actions) => action$.ofType("DO_SOMETHING", "PUT_SOMETHING").do(() => {}).switchMap(() => empty);
                                                                                                              ~~~~~~~~~                     [no-unsafe-switchmap]
const pipedMoreGetEpic = (action$: Actions) => action$.ofType("DO_SOMETHING", "GET_SOMETHING").pipe(tap(() => {}), switchMap(() => empty));
const pipedMorePutEpic = (action$: Actions) => action$.ofType("DO_SOMETHING", "PUT_SOMETHING").pipe(tap(() => {}), switchMap(() => empty));
                                                                                                                   ~~~~~~~~~                [no-unsafe-switchmap]

const patchedSymbolGetEffect = actions.ofType(GET_SOMETHING).do(() => {}).switchMap(() => empty);
const patchedSymbolPutEffect = actions.ofType(PUT_SOMETHING).do(() => {}).switchMap(() => empty);
                                                                          ~~~~~~~~~                                                         [no-unsafe-switchmap]
const pipedSymbolGetEffect = actions.ofType(GET_SOMETHING).pipe(tap(() => {}), switchMap(() => empty));
const pipedSymbolPutEffect = actions.ofType(PUT_SOMETHING).pipe(tap(() => {}), switchMap(() => empty));
                                                                               ~~~~~~~~~                                                    [no-unsafe-switchmap]

const pipedOfTypeGetEffect = actions.pipe(ofType(GET_SOMETHING), tap(() => {}), switchMap(() => empty));
const pipedOfTypePutEffect = actions.pipe(ofType(PUT_SOMETHING), tap(() => {}), switchMap(() => empty));
                                                                                ~~~~~~~~~                                                   [no-unsafe-switchmap]

const pipedOfTypeCamelCaseGetEffect = actions.pipe(ofType(GetSomething), tap(() => {}), switchMap(() => empty));
const pipedOfTypeCamelCasePutEffect = actions.pipe(ofType(PutSomething), tap(() => {}), switchMap(() => empty));
                                                                                        ~~~~~~~~~                                           [no-unsafe-switchmap]

[no-unsafe-switchmap]: Unsafe switchMap usage in effects and epics is forbidden
