/*
 * Copyright 2015-2017 Atomist Inc.
 *
 * 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 * as chatIdApi from "../ChatId";
import { ChatChannel } from "./ChatChannel";
import { ChatTeam } from "./ChatTeam";
import { Email } from "./Email";
import { Person } from "./Person";
import { UserPreferences } from "./UserPreferences";
export { ChatId };

/**
 * Type ChatId
 * Generated class exposing Atomist Cortex.
 * Fluent builder style class for use in testing and query by example.
 */
class ChatId implements chatIdApi.ChatId {

    private _channels: ChatChannel[];
    private _channelsCreated: ChatChannel[];
    private _chatTeam: ChatTeam;
    private _emails: Email[];
    private _id: string;
    private _isAdmin: boolean;
    private _isAtomistBot: boolean;
    private _isBot: boolean;
    private _isOwner: boolean;
    private _isPrimaryOwner: boolean;
    private _person: Person;
    private _preferences: UserPreferences;
    private _provider: string;
    private _screenName: string;
    private _timezoneLabel: string;

    private _nodeName = "ChatId";
    private _nodeTags = [ "ChatId", "-dynamic" ];

    /**
     * Implementation of GraphNode interface method.
     * For infrastructure, not user use
     */
    public nodeName(): string {
        return this._nodeName;
    }

    /**
     * Implementation of GraphNode interface method.
     * For infrastructure, not user use
     */
    public nodeTags(): string[] {
        return this._nodeTags;
    }

    /**
     * channels - ChatId -> ChatChannel
     *
     * @property {ChatChannel[]} channels
     */
    get channels(): ChatChannel[] {
        if (this._channels === undefined) {
            throw new Error(`Please use the relevant builder method to set property [channels] on stub ` +
                `[ChatId] before accessing it. It's probably called [withChannels]`);
        }
        return this._channels;
    }

    /**
     * Fluent builder method to add an element to the channels array
     */
    public addChannels(...channels_: ChatChannel[]) {
        if (this._channels === undefined) {
            this._channels = [];
        }
        this._channels = this._channels.concat(channels_);
        return this;
    }

    /**
     * channelsCreated - ChatId -> ChatChannel
     *
     * @property {ChatChannel[]} channelsCreated
     */
    get channelsCreated(): ChatChannel[] {
        if (this._channelsCreated === undefined) {
            throw new Error(`Please use the relevant builder method to set property [channelsCreated] on stub ` +
                `[ChatId] before accessing it. It's probably called [withChannelsCreated]`);
        }
        return this._channelsCreated;
    }

    /**
     * Fluent builder method to add an element to the channelsCreated array
     */
    public addChannelsCreated(...channelsCreated_: ChatChannel[]) {
        if (this._channelsCreated === undefined) {
            this._channelsCreated = [];
        }
        this._channelsCreated = this._channelsCreated.concat(channelsCreated_);
        return this;
    }

    /**
     * chatTeam - ChatId -> ChatTeam
     *
     * @property {ChatTeam} chatTeam
     */
    get chatTeam(): ChatTeam {
        if (this._chatTeam === undefined) {
            throw new Error(`Please use the relevant builder method to set property [chatTeam] on stub ` +
                `[ChatId] before accessing it. It's probably called [withChatTeam]`);
        }
        return this._chatTeam;
    }

    /**
     * Fluent builder method to set the chatTeam property
     */
    public withChatTeam(chatTeam_: ChatTeam) {
        this._chatTeam = chatTeam_;
        return this;
    }

    /**
     * emails - ChatId -> Email
     *
     * @property {Email[]} emails
     */
    get emails(): Email[] {
        if (this._emails === undefined) {
            throw new Error(`Please use the relevant builder method to set property [emails] on stub ` +
                `[ChatId] before accessing it. It's probably called [withEmails]`);
        }
        return this._emails;
    }

    /**
     * Fluent builder method to add an element to the emails array
     */
    public addEmails(...emails_: Email[]) {
        if (this._emails === undefined) {
            this._emails = [];
        }
        this._emails = this._emails.concat(emails_);
        return this;
    }

    /**
     * id
     *
     * @property {string} id
     */
    get id(): string {
        if (this._id === undefined) {
            throw new Error(`Please use the relevant builder method to set property [id] on stub ` +
                `[ChatId] before accessing it. It's probably called [withId]`);
        }
        return this._id;
    }

    /**
     * Fluent builder method to set the id property
     */
    public withId(id_: string) {
        this._id = id_;
        return this;
    }

    /**
     * isAdmin
     *
     * @property {boolean} isAdmin
     */
    get isAdmin(): boolean {
        if (this._isAdmin === undefined) {
            throw new Error(`Please use the relevant builder method to set property [isAdmin] on stub ` +
                `[ChatId] before accessing it. It's probably called [withIsAdmin]`);
        }
        return this._isAdmin;
    }

    /**
     * Fluent builder method to set the isAdmin property
     */
    public withIsAdmin(isAdmin_: boolean) {
        this._isAdmin = isAdmin_;
        return this;
    }

    /**
     * isAtomistBot
     *
     * @property {boolean} isAtomistBot
     */
    get isAtomistBot(): boolean {
        if (this._isAtomistBot === undefined) {
            throw new Error(`Please use the relevant builder method to set property [isAtomistBot] on stub ` +
                `[ChatId] before accessing it. It's probably called [withIsAtomistBot]`);
        }
        return this._isAtomistBot;
    }

    /**
     * Fluent builder method to set the isAtomistBot property
     */
    public withIsAtomistBot(isAtomistBot_: boolean) {
        this._isAtomistBot = isAtomistBot_;
        return this;
    }

    /**
     * isBot
     *
     * @property {boolean} isBot
     */
    get isBot(): boolean {
        if (this._isBot === undefined) {
            throw new Error(`Please use the relevant builder method to set property [isBot] on stub ` +
                `[ChatId] before accessing it. It's probably called [withIsBot]`);
        }
        return this._isBot;
    }

    /**
     * Fluent builder method to set the isBot property
     */
    public withIsBot(isBot_: boolean) {
        this._isBot = isBot_;
        return this;
    }

    /**
     * isOwner
     *
     * @property {boolean} isOwner
     */
    get isOwner(): boolean {
        if (this._isOwner === undefined) {
            throw new Error(`Please use the relevant builder method to set property [isOwner] on stub ` +
                `[ChatId] before accessing it. It's probably called [withIsOwner]`);
        }
        return this._isOwner;
    }

    /**
     * Fluent builder method to set the isOwner property
     */
    public withIsOwner(isOwner_: boolean) {
        this._isOwner = isOwner_;
        return this;
    }

    /**
     * isPrimaryOwner
     *
     * @property {boolean} isPrimaryOwner
     */
    get isPrimaryOwner(): boolean {
        if (this._isPrimaryOwner === undefined) {
            throw new Error(`Please use the relevant builder method to set property [isPrimaryOwner] on stub ` +
                `[ChatId] before accessing it. It's probably called [withIsPrimaryOwner]`);
        }
        return this._isPrimaryOwner;
    }

    /**
     * Fluent builder method to set the isPrimaryOwner property
     */
    public withIsPrimaryOwner(isPrimaryOwner_: boolean) {
        this._isPrimaryOwner = isPrimaryOwner_;
        return this;
    }

    /**
     * person - ChatId -> Person
     *
     * @property {Person} person
     */
    get person(): Person {
        if (this._person === undefined) {
            throw new Error(`Please use the relevant builder method to set property [person] on stub ` +
                `[ChatId] before accessing it. It's probably called [withPerson]`);
        }
        return this._person;
    }

    /**
     * Fluent builder method to set the person property
     */
    public withPerson(person_: Person) {
        this._person = person_;
        return this;
    }

    /**
     * preferences - ChatId -> UserPreferences
     *
     * @property {UserPreferences} preferences
     */
    get preferences(): UserPreferences {
        if (this._preferences === undefined) {
            throw new Error(`Please use the relevant builder method to set property [preferences] on stub ` +
                `[ChatId] before accessing it. It's probably called [withPreferences]`);
        }
        return this._preferences;
    }

    /**
     * Fluent builder method to set the preferences property
     */
    public withPreferences(preferences_: UserPreferences) {
        this._preferences = preferences_;
        return this;
    }

    /**
     * provider
     *
     * @property {string} provider
     */
    get provider(): string {
        if (this._provider === undefined) {
            throw new Error(`Please use the relevant builder method to set property [provider] on stub ` +
                `[ChatId] before accessing it. It's probably called [withProvider]`);
        }
        return this._provider;
    }

    /**
     * Fluent builder method to set the provider property
     */
    public withProvider(provider_: string) {
        this._provider = provider_;
        return this;
    }

    /**
     * screenName
     *
     * @property {string} screenName
     */
    get screenName(): string {
        if (this._screenName === undefined) {
            throw new Error(`Please use the relevant builder method to set property [screenName] on stub ` +
                `[ChatId] before accessing it. It's probably called [withScreenName]`);
        }
        return this._screenName;
    }

    /**
     * Fluent builder method to set the screenName property
     */
    public withScreenName(screenName_: string) {
        this._screenName = screenName_;
        return this;
    }

    /**
     * timezoneLabel
     *
     * @property {string} timezoneLabel
     */
    get timezoneLabel(): string {
        if (this._timezoneLabel === undefined) {
            throw new Error(`Please use the relevant builder method to set property [timezoneLabel] on stub ` +
                `[ChatId] before accessing it. It's probably called [withTimezoneLabel]`);
        }
        return this._timezoneLabel;
    }

    /**
     * Fluent builder method to set the timezoneLabel property
     */
    public withTimezoneLabel(timezoneLabel_: string) {
        this._timezoneLabel = timezoneLabel_;
        return this;
    }

}
