#!/bin/bash


echo ""
echo ""
echo ""
echo ""


if [ "$#" -eq 0 ]; then
    cat <<EOF
Usage: $0 <target> <need>

    <target> :
                sql ...
                ts ...
                cs ...
                html ...
                ng ...
EOF
    exit 1
fi

readonly TARGET=$1
readonly NEED=$2

#####################
###      SQL      ###
#####################



if [ "$TARGET" == "sql" ] && [ -z $NEED ]; then
    echo "try these"
    echo "cookbook sql addColumn <table> <column>"
    echo "cookbook sql dropColumn <table> <column>"
    echo "cookbook sql addFk <table> <column> <reftable>"
    echo "cookbook sql alterCol <table> <column>"
    echo "cookbook sql addUser <username>"
    echo "cookbook sql addCaseloads"
    echo "cookbook sql fillPatientCollision"
    echo "cookbook sql query <queryname>"

    exit 0
fi

if [ "$TARGET" == "sql" ] && [ "$NEED" == "addColumn" ]; then
    echo "IF NOT EXISTS(SELECT 1 FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = '${3:-<table>}' AND COLUMN_NAME = '${4:-<column>}')"
    echo "BEGIN"
    echo "    EXEC('ALTER TABLE [dbo].[${3:-<table>}] ADD [${4:-<column>}] [INT] NULL')"
    echo "END"
    exit 0
fi

if [ "$TARGET" == "sql" ] && [ "$NEED" == "dropColumn" ]; then
    echo "IF EXISTS(SELECT 1 FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = '${3:-<table>}' AND COLUMN_NAME = '${4:-<column>}')"
    echo "BEGIN"
    echo "    EXEC('ALTER TABLE [dbo].[${3:-<table>}] drop column [${4:-<column>}]')"
    echo "END"
    exit 0
fi

if [ "$TARGET" == "sql" ] && [ "$NEED" == "addFk" ]; then
    echo "IF EXISTS(SELECT 1 FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = '${3:-<table>}' AND COLUMN_NAME = '${4:-<column>}')"
    echo "BEGIN"
    echo "    EXEC('ALTER TABLE [dbo].[${3:-<table>}] ADD CONSTRAINT [FK_${VALUE1}_${VALUE2}] FOREIGN KEY (${4:-<column>}) REFERENCES [dbo].[${5:-<reftable>}](${4:-<column>})')"
    echo "END"
    exit 0
fi


if [ "$TARGET" == "sql" ] && [ "$NEED" == "alterCol" ]; then
    echo "IF EXISTS(SELECT 1 FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = '${3:-<table>}' AND COLUMN_NAME = '${4:-<column>}')"
    echo "BEGIN"
    echo "    EXEC('ALTER TABLE [dbo].[${3:-<table>}] ALTER COLUMN [${4:-<column>}] NVARCHAR(1000) NULL')"
    echo "END"
    exit 0
fi

if [ "$TARGET" == "sql" ] && [ "$NEED" == "addUser" ]; then
    echo "cookbook sql addUser ${3:-login} ${4:-email} ${5:-firstname} ${6:-lastname}"
    cat <<EOF

    IF not EXISTS(SELECT 1 FROM SEC_User WHERE login = '${3:-<table>}')
    BEGIN

    DECLARE @Login VARCHAR(50) = '${3:-login}';
    DECLARE @Email VARCHAR(50) = '${4:-email}';
    DECLARE @FirstName VARCHAR(50) = '${5:-firstname}';
    DECLARE @LastName VARCHAR(50) = '${6:-lastname}';


    insert into SEC_User (IsEnabled, IsLockedOut, CreationDate, CreationUser, RequiresPasswordChange, [Password], Salt, Login, Email, FirstName, LastName)
    select 1,0,CURRENT_TIMESTAMP,'mrobinson',0,SEC_User.[Password], SEC_User.Salt, @Login, @Email, @FirstName, @LastName
    from SEC_User where SEC_User.Login = 'mrobinson';


    WITH cte_roles AS (
        select SEC_Role.RoleId 
        from SEC_Role 
        where SEC_Role.IsEnabled = 1 
        and SEC_Role.Name not like '%DEV%'
        and SEC_Role.Name not like '%ADMIN%'
        and SEC_Role.Name not like '%COMPLETE%'
        and (
            SEC_Role.Name like '%COMMON%' or
            SEC_Role.Name like '%APSS%' or
            SEC_Role.Name like '%ZINC%' or
            SEC_Role.Name like '%ONCO%'
        )
    )


    insert into SEC_UserRole (CreationDate, CreationUser, UserId, RoleId)
    select CURRENT_TIMESTAMP, 'sql', SEC_User.UserId , cte_roles.RoleId
    from SEC_User 
    cross join cte_roles
    where SEC_User.Login = @Login

    END
    
EOF
    
    exit 0
fi

if [ "$TARGET" == "sql" ] && [ "$NEED" == "addCaseloads" ]; then
    cat <<EOF

    INSERT INTO UserPatientCaseload(UserId, ApplicationId, CreationDate, IsOwner, IsReviewed, PatientId)
    SELECT 11,11,CURRENT_TIMESTAMP,1,0,l.patientId
    FROM (VALUES
        (101406), 	(101455), 	(101509), 	(101672), 	(101959), 	(102641), 	(103335), 	(103740), 	(104329), 	
        (104707), 	(105647), 	(107933), 	(108332), 	(108714), 	(109326), 	(109443), 	(109859), 	(113495), 	
        (114706), 	(115081), 	(115529), 	(118039), 	(118358), 	(118919), 	(120407), 	(120414), 	(120958), 	
        (121546), 	(123160), 	(124506), 	(124694), 	(127042), 	(127801), 	(128684), 	(129644), 	(129791), 	
        (130350), 	(131939), 	(132827), 	(132914), 	(133525), 	(134191), 	(134694), 	(135063), 	(135629), 	
        (136820), 	(137493), 	(138257), 	(139163), 	(139551), 	(139795), 	(139938), 	(139985), 	(140130), 	
        (140150), 	(140156), 	(140172), 	(140181), 	(140183), 	(140186), 	(140198), 	(140204), 	(140234), 	
        (140240), 	(140243), 	(140245), 	(140252), 	(140253), 	(140254), 	(140256), 	(140260), 	(140261), 	
        (140262), 	(140270), 	(140271), 	(140273), 	(140284), 	(140291), 	(140304), 	(140319), 	(140336), 	
        (140354), 	(140492), 	(141187), 	(141563), 	(142299), 	(142400), 	(143151), 	(143180), 	(143210), 	
        (143239), 	(143240), 	(143250), 	(143256), 	(143257), 	(143271), 	(143282), 	(143284), 	(144445)
    ) AS l (patientId)
    WHERE NOT EXISTS (
        SELECT 1 FROM UserPatientCaseload t WHERE t.PatientId = l.patientId AND t.UserId = 11 AND t.ApplicationId = 11
    )

EOF
    
    exit 0
fi


if [ "$TARGET" == "sql" ] && [ "$NEED" == "fillPatientCollision" ]; then
    cat <<EOF

declare @Pcode table (PatientId int, ExtCode NVARCHAR(100));
declare @PPcode table (PatientId1 int, PatientId2 int, ExtCode NVARCHAR(100));

insert into @Pcode
		select PatientId, PrimaryExternalCode as ExtCode from Patient
		union
		select PatientId, ExternalCode as ExtCode from PatientExternalCode

insert into @PPcode
select * from (
	select 
		case when Pcode.PatientId < Pcode2.PatientId then Pcode.PatientId else Pcode2.PatientId end as PatientId1,
		case when Pcode.PatientId > Pcode2.PatientId then Pcode.PatientId else Pcode2.PatientId end as PatientId2,
		Pcode.ExtCode
	from @Pcode Pcode
	inner join @Pcode Pcode2 
	on Pcode2.ExtCode = Pcode.ExtCode 
	and Pcode.PatientId <> Pcode2.PatientId
) PPcode
group by PPcode.PatientId1, PPcode.PatientId2, PPcode.ExtCode


insert into PatientCollision (PatientIdCollision, PatientIdExisting, ExternalCode, CreationDate, CreationUser)
select PPcode.PatientId1, PPcode.PatientId2, PPcode.ExtCode, CURRENT_TIMESTAMP, 'sqlscript'
from @PPcode PPcode 
where not exists ( select 1 from PatientCollision where PatientCollision.PatientIdCollision = PPcode.PatientId1 and PatientCollision.PatientIdExisting = PPcode.PatientId2 and PatientCollision.ExternalCode = PPcode.ExtCode )


SELECT * FROM [PatientCollision]

EOF
    exit 0
fi


if [ "$TARGET" == "sql" ] && [ "$NEED" == "query" ] && [ -z "$3" ]; then
    echo "precooked query : "
    echo "cookbook sql query userRole"
    echo "cookbook sql query schema"
    exit 0
fi

if [ "$TARGET" == "sql" ] && [ "$NEED" == "query" ] && [ "$3" == "userRole" ]; then
    cat <<EOF

    select *
    from (

        select SEC_User.Login as UserName, SEC_Role.Name as RoleName
        from SEC_User
        inner join SEC_UserRole on SEC_UserRole.UserId = SEC_User.UserId
        inner join SEC_Role on SEC_Role.RoleId = SEC_UserRole.RoleId
        where SEC_User.IsEnabled = 1 and SEC_Role.IsEnabled = 1

        union

        select SEC_User.Login as UserName, SEC_Role.Name as RoleName
        from SEC_User
        inner join SEC_UserGroupUser on SEC_UserGroupUser.UserId = SEC_User.UserId
        inner join SEC_UserGroupRole on SEC_UserGroupRole.UserGroupId = SEC_UserGroupUser.UserGroupId
        inner join SEC_Role on SEC_Role.RoleId = SEC_UserGroupRole.RoleId
        where SEC_User.IsEnabled = 1 and SEC_Role.IsEnabled = 1

    ) as UserRole

EOF
    exit 0
fi

if [ "$TARGET" == "sql" ] && [ "$NEED" == "query" ] && [ "$3" == "schema" ]; then
    cat <<EOF

    select *
    from (
        SELECT 
            t.name AS TableName,
            c.name AS ColumnName,
            ty.name AS DataType,
            c.is_nullable AS IsNullable,
            CASE WHEN pk.ColumnName IS NOT NULL THEN 'YES' ELSE 'NO' END AS IsPrimaryKey
        FROM sys.tables t
        JOIN sys.columns c ON t.object_id = c.object_id
        JOIN sys.types ty ON c.user_type_id = ty.user_type_id
        LEFT JOIN (
            SELECT 
                i.object_id,
                ic.column_id,
                c.name AS ColumnName
            FROM sys.indexes i
            JOIN sys.index_columns ic ON i.object_id = ic.object_id AND i.index_id = ic.index_id
            JOIN sys.columns c ON ic.object_id = c.object_id AND ic.column_id = c.column_id
            WHERE i.is_primary_key = 1
        ) pk ON c.object_id = pk.object_id AND c.column_id = pk.column_id
        ORDER BY t.name, c.column_id;    
    ) as DbSchema

EOF
    exit 0
fi





#####################
###   C sharp     ###
#####################



if [ "$TARGET" == "cs" ] && [ -z "$NEED" ]; then
    echo "cookbook cs mock serviceName"
    exit 0
fi



if [ "$TARGET" == "cs" ] && [ "$NEED" == "mock" ]; then
    echo "private Mock<${3:-Service}> _${3:-Service}Mock;"
    echo ""
    echo "    _${3:-Service}Mock = new Mock<${3:-Service}>(MockBehavior.Strict);"
    echo ""
    echo "        ${3:-Service} = _${3:-Service}Mock.Object,"
    echo ""
    exit 0
fi


if [ "$TARGET" == "cs" ] && [ "$NEED" == "resx" ]; then
    echo ""
    echo "[Display(ResourceType = typeof(${4:-<App>}esources), Name = nameof(${4:-<App>}Resources.${3:-<FieldName>}))]"
    echo ""
    echo "can also use this regex"
    echo "s/ *public [^ ]\+ \([a-zA-Z]\+\)/[Display(ResourceType = typeof(${4:-<App>}esources), Name = nameof(${4:-<App>}esources.${3:-<FieldName>}_\1))]\r\0/"
    echo ""
    exit 0
fi




#####################
###   typescript  ###
#####################



if [ "$TARGET" == "ts" ] && [ -z "$NEED" ]; then
    echo "cookbook ts table modelName filterName"
    echo "cookbook ts modal modelName"
    echo "cookbook ts form modelName"
    exit 0
fi


if [ "$TARGET" == "ts" ] && [ "$NEED" == "table" ]; then
cat << EOF
    public modelPrototype: MetadataDefinition = ${3:-Model}.prototype[MetadataDefinition.METADATA_CONTAINER_PROPERTY_NAME];
    public modelCtor = ${3:-Model};
    public model: ${3:-Model};
    public items: Array<${3:-Model}> = [];

    public filterPrototype: MetadataDefinition = ${4:-Filter}.prototype[MetadataDefinition.METADATA_CONTAINER_PROPERTY_NAME];
    public filterCtor = ${4:-Filter};
    public presetFilters: Array<PresetFilter<${4:-Filter}>>;
    public defaultFilter = new ${4:-Filter}({});
    public filter = new ${4:-Filter}(this.defaultFilter);

    public async onEvent(event: any): Promise<void> {
        console.log(event);
        if (event.type === DataFormEventType.ViewItem) {
            await this._promptService.promptFormData(
                'view modal title',
                new ${3:-Model}(event.payload),
                this.modelPrototype,
                { modalReadOnly: true });
        }
        if (event.type === DataFormEventType.EditItem) {
            const promptResult = await this._promptService.promptFormData(
                'edit modal title',
                event.payload,
                this.modelPrototype,
                { modalReadOnly: false });
            if (promptResult.confirmed === true) {
                console.log('edited', promptResult.response);
            }
        }
        if (event.type === DataFormEventType.AddNewItem) {
            const promptResult = await this._promptService.promptFormData(
                'add modal title',
                new ${3:-Model}(),
                this.modelPrototype,
                { modalReadOnly: false });
            if (promptResult.confirmed === true) {
                console.log('added', promptResult.response);
                this.items.push(promptResult.response as any as ${3:-Model});
            }
        }

        if (event.type === DataFormEventType.DeleteItem) {
            const promptResult = await this._promptService.confirm(
                'Prompt_Delete_Confirm_Title',
                'Prompt_Delete_Confirm_Message');
            if (promptResult.confirmed === true) {
                console.log('deleted', promptResult.response);
                this.items = this.items.filter(x => x !== event.payload);
            }
        }
    }

    constructor(
        private readonly _promptService: PromptService
    ) { }
EOF
    exit 0
fi



if [ "$TARGET" == "ts" ] && [ "$NEED" == "modal" ]; then
cat << EOF
export class ${3:-Model}ModalComponent extends ModalableComponentAdaptor {
    @ViewChild(FormMdcComponent) public form: FormMdcComponent;
    public modelPrototype: MetadataDefinition = ${3:-Model}.prototype[MetadataDefinition.METADATA_CONTAINER_PROPERTY_NAME];
    public model: ${3:-Model};
    public readonly: boolean;
    public parameters: ${3:-Model}ModalParameter;

    public async onBeforeOpen(parameter: ${3:-Model}ModalParameter): Promise<void> {
        this.parameters = parameter;
        this.model = parameter.model;
        this.readonly = parameter.readonly;
    }

    public async onBeforeOkAsync(): Promise<boolean> {
        this.form.validate();
        const result = await FormValidationUtils.validateAndSaveForm(this.form,
            this.model,
            x => this.save(x));
        return result;
    }

    private async save(form: ${3:-Model}): Promise<${3:-Model}> {
        return await Promise.resolve(form);
    }

    public onEvent(event: any): void {
        console.log(event);
    }
}

export class ${3:-Model}ModalParameter extends ModalParameters {
    public model: ${3:-Model};
    public readonly: boolean;

    constructor(init?: Partial<${3:-Model}ModalParameter>) {
        super();
        this.title = '${3:-Model}_title';
        this.height = '80%';
        this.showCancel = false;
        this.hasExpandButton = true;
        this.readonly = false;
        Object.assign(this, init);
    }
}

@Injectable()
export class ${3:-Model}PromptService {

    constructor(
        private readonly _modalService: ModalService,
    ) { }

    public async edit(model: ${3:-Model}): Promise<boolean> {
        const parameters = new ${3:-Model}ModalParameter ({
            model: new ${3:-Model}(model),
            readonly: false
        });
        const editResult = await this._modalService.showModal(${3:-Model}ModalComponent, parameters);
        if (editResult.result === ModalResultEnum.ModalResultOk) {
            Object.assign(model, parameters.model);
            return true;
        }
        return false;
    }
}

EOF
    exit 0
fi


if [ "$TARGET" == "ts" ] && [ "$NEED" == "form" ]; then
cat << EOF
    public modelPrototype: MetadataDefinition = ${3:-Model}.prototype[MetadataDefinition.METADATA_CONTAINER_PROPERTY_NAME];
    public modelCtor = ${3:-Model};
    public model: ${3:-Model};
    public readonly: boolean;

    constructor(
    ) { }

    public onEvent($event: DataFormEvent): void {
        console.log($event);
    }
EOF
    exit 0
fi




#####################
###      html     ###
#####################


if [ "$TARGET" == "html" ] && [ -z "$NEED" ]; then
    echo "cookbook html table"
    echo "cookbook html modal"
    echo "cookbook html form"
    exit 0
fi


if [ "$TARGET" == "html" ] && [ "$NEED" == "table" ]; then
cat << EOF
<shared-preset-filters key="${4:-Filter}"
                       [presetFilters]="presetFilters"
                       [(currentFilter)]="filter"
                       [ignoredFields]="[]"
                       [filterCtor]="filterCtor"
                       (presetFilterSelected)="onEvent(\$event)"
                       (customPresetFilterSelected)="onEvent(\$event)"
                       (customPresetFilterAdded)="onEvent(\$event)" />

<lumed-template-drawer-container>
    <lumed-display-filter-drawer-button [filterCtor]="filterCtor"
                                        [defaultFilter]="defaultFilter"
                                        (applyFilter)="onEvent(\$event)"
                                        (filterChange)="onEvent(\$event)"
                                        [(filter)]="filter">
        <ng-template #customFilterBox
                     let-filter>
            <lumed-filter-box [showVertical]="true"
                              [isCollapsedEnabled]="true"
                              [areFiltersButtonsEnabled]="true"
                              [focusFirstErrorOnValidate]="true"
                              [resetFilterAfterInit]="true"
                              (filterReset)="onEvent(\$event)"
                              (onFilterChange)="onEvent(\$event)"
                              name="that-filter-box">
                <lumed-filter-source [source]="filter"
                                     [defaultValues]="defaultFilter"
                                     [collapsedMembers]="[]" />

            </lumed-filter-box>
        </ng-template>
    </lumed-display-filter-drawer-button>

    <lumed-data-table-control class=""
                              [modelsPrototype]="modelPrototype"
                              [models]="items"
                              (eventChannel)="onEvent(\$event)"
                              [isReadOnly]="false"
                              [isFixed]="true"
                              noDataRowText="No data fits the current filters"
                              [pageSize]="30"
                              footerAdditionalInfo="[maxResults]='100'"
                              [actionMenuTemplate]="actionMenu"
                              [hasDetailButton]="true"
                              [hasAddButton]="true"
                              [hasEditButton]="true"
                              [hasDeleteButton]="true"
                              [hasSelectionCheckbox]="false"
                              (selectedItemsChange)="onEvent($event)"
                              [isMultipleSelection]="false"
                              [editableOnlyWhenSelected]="false"
                              (lumedColumnConfigChange)="onEvent($event)"
                              [allowColumnReordering]="true"
                              [allowColumnResizing]="true"
                              [autoSelectFirstItem]="true"
                              [columnsOptions]="{}"
                              [columnsOrder]="[]"
                              lumedExcelExport
                              [lumedExcelExportDisabled]="false">

        <lumed-button-mdc additional-button
                          class="filter-button"
                          tooltip="additional button">
            :)
        </lumed-button-mdc>
    </lumed-data-table-control>

    <ng-template #actionMenu
                 let-item="item">
        <button mat-menu-item>B==D</button>
    </ng-template>

<lumed-template-drawer-container>
EOF
    exit 0;
fi


if [ "$TARGET" == "html" ] && [ "$NEED" == "modal" ]; then
cat << EOF
<lumed-form-mdc #form="ngForm"
                name="form-data-demo"
                ngForm
                [form]="form">
    <lumed-data-form name="Form DATA"
                     [disabledFields]="[]"
                     [modelPrototype]="modelPrototype"
                     [model]="model"
                     [isReadOnly]="readonly"
                     (eventChannel)="onEvent($event)" />
</lumed-form-mdc>
EOF
    exit 0
fi


if [ "$TARGET" == "html" ] && [ "$NEED" == "form" ]; then
cat << EOF
<lumed-form-mdc #form="ngForm"
                name="form-data-demo"
                ngForm
                [form]="form">
    <lumed-data-form name="Form DATA"
                     [disabledFields]="[]"
                     [modelPrototype]="modelPrototype"
                     [model]="model"
                     [isReadOnly]="readonly"
                     (eventChannel)="onEvent($event)" />
</lumed-form-mdc>
EOF
    exit 0
fi

#####################
###    ANGULAR    ###
#####################



if [ "$TARGET" == "ng" ] && [ -z $NEED ]; then
    echo "try these"
    echo "cookbook ng g c <component name>"


    exit 0
fi


if [ "$TARGET" == "ng" ] && [ "$NEED" == "g" ] && [ "$3" == "c" ]; then
    cat <<EOF
ng g c --standalone false ${4:-<component>}
EOF
    exit 0;
fi
#####################
###  Unsupported  ###
#####################

echo "unsupported <target> $TARGET"
echo "at least not yet"
exit 1  # Exit with a non-zero status to indicate an error or unsupported target


