#include <iostream>
#include <osl/osl.h>

void
perforate(osl_relation_p rel, int i) {
    int r = rel->nb_rows;
    int c = rel->nb_columns - rel->nb_parameters - 1; /* we want the new constraint to be left of 1 and global parameters */

    osl_relation_insert_blank_row(rel, r);
    osl_relation_insert_blank_column(rel, c);
    rel->nb_local_dims++;

    auto row = rel->m[r];
    osl_int_set_si(rel->precision, &row[c], 2);
    osl_int_set_si(rel->precision, &row[1+i], -1); /* iterators come first, first column is e/i */
}

int main(int argc, char *argv[]) {
    if(argc != 5) {
        std::cerr << "usage: <INPUT SCOP> <OUTPUT SCOP> <STATEMENT> <ITERATOR>\n";
        return -1;
    }

    int statement = atoi(argv[3]);
    int iterator = atoi(argv[4]);

    auto *fp = fopen(argv[1], "r");
    if(!fp) {
        std::cerr << "openscop read failed\n";
        return -1;
    }
    auto scop = osl_scop_read(fp);
    fclose(fp);
    
    /* find statement */
    int i = statement;
    auto s = scop->statement;
    for(; s && i; s = s->next) {
        i--;
    }

    if(i || !s) {
        std::cerr << "statement not found\n";
        return -1;
    }

    if(s->domain->nb_output_dims <= iterator) {
        std::cerr << "iterator not found\n";
        return -1;
    }

    perforate(s->domain, iterator);
    
    fp = fopen(argv[2], "w");
    if(!fp) {
        std::cerr << "openscop write failed\n";
        return -1;
    }
    osl_scop_print(fp, scop);
    fclose(fp);

    osl_scop_free(scop);
    return 0;
}