/*
 * 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 commitApi from "../Commit";
import { Application } from "./Application";
import { Build } from "./Build";
import { Fingerprint } from "./Fingerprint";
import { GitHubId } from "./GitHubId";
import { HerokuApp } from "./HerokuApp";
import { Issue } from "./Issue";
import { ParentImpact } from "./ParentImpact";
import { PullRequest } from "./PullRequest";
import { Push } from "./Push";
import { Repo } from "./Repo";
import { Status } from "./Status";
import { Tag } from "./Tag";
export { Commit };

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

    private _apps: Application[];
    private _author: GitHubId;
    private _builds: Build[];
    private _committer: GitHubId;
    private _fingerprints: Fingerprint[];
    private _herokuApps: HerokuApp[];
    private _impact: ParentImpact;
    private _message: string;
    private _pullRequests: PullRequest[];
    private _pushes: Push[];
    private _repo: Repo;
    private _resolves: Issue[];
    private _sha: string;
    private _statuses: Status[];
    private _tags: Tag[];
    private _timestamp: string;

    private _nodeName = "Commit";
    private _nodeTags = [ "Commit", "-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;
    }

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

    /**
     * Fluent builder method to add an element to the apps array
     */
    public addApps(...apps_: Application[]) {
        if (this._apps === undefined) {
            this._apps = [];
        }
        this._apps = this._apps.concat(apps_);
        return this;
    }

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

    /**
     * Fluent builder method to set the author property
     */
    public withAuthor(author_: GitHubId) {
        this._author = author_;
        return this;
    }

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

    /**
     * Fluent builder method to add an element to the builds array
     */
    public addBuilds(...builds_: Build[]) {
        if (this._builds === undefined) {
            this._builds = [];
        }
        this._builds = this._builds.concat(builds_);
        return this;
    }

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

    /**
     * Fluent builder method to set the committer property
     */
    public withCommitter(committer_: GitHubId) {
        this._committer = committer_;
        return this;
    }

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

    /**
     * Fluent builder method to add an element to the fingerprints array
     */
    public addFingerprints(...fingerprints_: Fingerprint[]) {
        if (this._fingerprints === undefined) {
            this._fingerprints = [];
        }
        this._fingerprints = this._fingerprints.concat(fingerprints_);
        return this;
    }

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

    /**
     * Fluent builder method to add an element to the herokuApps array
     */
    public addHerokuApps(...herokuApps_: HerokuApp[]) {
        if (this._herokuApps === undefined) {
            this._herokuApps = [];
        }
        this._herokuApps = this._herokuApps.concat(herokuApps_);
        return this;
    }

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

    /**
     * Fluent builder method to set the impact property
     */
    public withImpact(impact_: ParentImpact) {
        this._impact = impact_;
        return this;
    }

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

    /**
     * Fluent builder method to set the message property
     */
    public withMessage(message_: string) {
        this._message = message_;
        return this;
    }

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

    /**
     * Fluent builder method to add an element to the pullRequests array
     */
    public addPullRequests(...pullRequests_: PullRequest[]) {
        if (this._pullRequests === undefined) {
            this._pullRequests = [];
        }
        this._pullRequests = this._pullRequests.concat(pullRequests_);
        return this;
    }

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

    /**
     * Fluent builder method to add an element to the pushes array
     */
    public addPushes(...pushes_: Push[]) {
        if (this._pushes === undefined) {
            this._pushes = [];
        }
        this._pushes = this._pushes.concat(pushes_);
        return this;
    }

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

    /**
     * Fluent builder method to set the repo property
     */
    public withRepo(repo_: Repo) {
        this._repo = repo_;
        return this;
    }

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

    /**
     * Fluent builder method to add an element to the resolves array
     */
    public addResolves(...resolves_: Issue[]) {
        if (this._resolves === undefined) {
            this._resolves = [];
        }
        this._resolves = this._resolves.concat(resolves_);
        return this;
    }

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

    /**
     * Fluent builder method to set the sha property
     */
    public withSha(sha_: string) {
        this._sha = sha_;
        return this;
    }

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

    /**
     * Fluent builder method to add an element to the statuses array
     */
    public addStatuses(...statuses_: Status[]) {
        if (this._statuses === undefined) {
            this._statuses = [];
        }
        this._statuses = this._statuses.concat(statuses_);
        return this;
    }

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

    /**
     * Fluent builder method to add an element to the tags array
     */
    public addTags(...tags_: Tag[]) {
        if (this._tags === undefined) {
            this._tags = [];
        }
        this._tags = this._tags.concat(tags_);
        return this;
    }

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

    /**
     * Fluent builder method to set the timestamp property
     */
    public withTimestamp(timestamp_: string) {
        this._timestamp = timestamp_;
        return this;
    }

}
