#! /usr/bin/python3
import os
import sys
import generator_utils as gen

template = """// @{generatedby}@
/* ///////////////////////// The MPI Bugs Initiative ////////////////////////

  Origin: @{origin}@

  Description: @{shortdesc}@
    @{longdesc}@

    Version of MPI: Conforms to MPI 1.1, does not require MPI 2 implementation

BEGIN_MPI_FEATURES
    P2P!basic: Lacking
    P2P!nonblocking: Lacking
    P2P!persistent: Lacking
    COLL!basic: Lacking
    COLL!nonblocking: Lacking
    COLL!persistent: Lacking
    COLL!tools: Lacking
    RMA: @{rmafeature}@
END_MPI_FEATURES

BEGIN_MBI_TESTS
  $ mpirun -np 2 ${EXE}
  | @{outcome}@
  | @{errormsg}@
END_MBI_TESTS
//////////////////////       End of MBI headers        /////////////////// */

#include <mpi.h>
#include <stdio.h>
#include <stdlib.h>

#define N 20

int main(int argc, char **argv) {
  int rank, numProcs;

  MPI_Init(&argc, &argv);
  MPI_Comm_size(MPI_COMM_WORLD, &numProcs);
  MPI_Comm_rank(MPI_COMM_WORLD, &rank);

  if (numProcs < 2)
    printf("MBI ERROR: This test needs at least 2 processes to produce a bug!\\n");

  int *winbuf = malloc(N * sizeof(int));

  MPI_Win win;
  MPI_Win_create(winbuf, N * sizeof(int), 1, MPI_INFO_NULL, MPI_COMM_WORLD, &win);

  MPI_Datatype type = MPI_INT;
  int target = 1;

  @{epoch}@

  if (rank == 0) {
    @{epoch2}@

    @{init}@
    @{operation}@

    @{finEpoch2}@
  }

  @{finEpoch}@

  MPI_Win_free(&win);

  free(winbuf);

  MPI_Finalize();

  printf("Rank %d finished normally\\n", rank);
  return 0;
}
"""


for e1 in gen.epoch:
    for p in gen.rma:
        patterns = {}
        patterns = {'e1': e1, 'p': p}
        patterns['origin'] = "MPI-Corrbench"
        patterns['generatedby'] = f'DO NOT EDIT: this file was generated by {os.path.basename(sys.argv[0])}. DO NOT EDIT.'
        patterns['rmafeature'] = 'Yes'
        patterns['p'] = p
        patterns['e1'] = e1
        patterns['epoch'] = gen.epoch[e1]("1")
        patterns['finEpoch'] = gen.finEpoch[e1]("1")
        patterns['epoch2'] = ""
        patterns['finEpoch2'] = ""
        patterns['init'] = gen.init[p]("1")
        patterns['operation'] = gen.operation[p]("1")

        # Generate a code correct
        replace = patterns.copy()
        replace['shortdesc'] = 'Correct code'
        replace['longdesc'] = 'Correct code'
        replace['outcome'] = 'OK'
        replace['errormsg'] = 'OK'
        gen.make_file(template, f'ReqLifecycle_RMA_{e1}_{p}_ok.c', replace)

        # Generate a code with missing open epoch
        replace = patterns.copy()
        replace['shortdesc'] = f"Request lifecycle, missing open {e1} epoch"
        replace['longdesc'] = f"Request lifecycle, missing open {e1} epoch"
        replace['outcome'] = 'ERROR: MissingStart'
        replace['errormsg'] = '@{e1}@ at @{filename}@:@{line:MBIERROR}@ has missing'
        replace['epoch'] = f"/* MBIERROR MISSING: {gen.epoch[e1]('1')} */"
        gen.make_file(template, f'ReqLifecycle_RMA_MissingOpen_{e1}_{p}_nok.c', replace)

        # Generate a code with missing close epoch
        replace = patterns.copy()
        replace['shortdesc'] = f"Request lifecycle, missing close {e1} epoch"
        replace['longdesc'] = f"Request lifecycle, missing close {e1} epoch"
        replace['outcome'] = 'ERROR: MissingWait'
        replace['errormsg'] = '@{e1}@ at @{filename}@:@{line:MBIERROR}@ has missing'
        replace['epoch'] = gen.epoch[e1]("1")
        replace['finEpoch'] = f"/* MBIERROR MISSING: {gen.finEpoch[e1]('1')} */"
        gen.make_file(template, f'ReqLifecycle_RMA_MissingClose_{e1}_{p}_nok.c', replace)

for e1 in gen.epoch:
    for e2 in gen.epoch:
        for p in gen.rma:
            patterns = {}
            patterns = {'e1': e1, 'e2': e2, 'p': p}
            patterns['origin'] = "MPI-Corrbench"
            patterns['generatedby'] = f'DO NOT EDIT: this file was generated by {os.path.basename(sys.argv[0])}. DO NOT EDIT.'
            patterns['rmafeature'] = 'Yes'
            patterns['p'] = p
            patterns['e1'] = e1
            patterns['e2'] = e2
            patterns['epoch'] = gen.epoch[e1]("1")
            patterns['finEpoch'] = gen.finEpoch[e1]("1")
            patterns['epoch2'] = gen.epoch[e2]("1") + " /* MBIERROR */"
            patterns['finEpoch2'] = gen.finEpoch[e2]("1") + " /* MBIERROR */"
            patterns['init'] = gen.init[p]("1")
            patterns['operation'] = gen.operation[p]("1")

            # Generate a code with epoch into an epoch
            replace = patterns.copy()
            replace['shortdesc'] = f"Request lifecycle, {e2} epoch into {e1} epoch"
            replace['longdesc'] = f"Request lifecycle, {e2} epoch into {e1} epoch"
            replace['outcome'] = 'ERROR: MissingWait' #FIXME: New type of error
            replace['errormsg'] = '@{e2}@ at @{filename}@:@{line:MBIERROR}@ has in an other epoch'
            gen.make_file(template, f'ReqLifecycle_RMA_TwoEpoch_{e1}_{e2}_{p}_nok.c', replace)
