!==================================================================================================================================================================================
! Copyright (c) 2018, Miroslav Stoyanov
!
! This file is part of
! Toolkit for Adaptive Stochastic Modeling And Non-Intrusive ApproximatioN: TASMANIAN
!
! Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
!
! 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
!
! 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions
!    and the following disclaimer in the documentation and/or other materials provided with the distribution.
!
! 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse
!    or promote products derived from this software without specific prior written permission.
!
! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
! INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
! IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
! OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
! OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
! OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
!
! UT-BATTELLE, LLC AND THE UNITED STATES GOVERNMENT MAKE NO REPRESENTATIONS AND DISCLAIM ALL WARRANTIES, BOTH EXPRESSED AND IMPLIED.
! THERE ARE NO EXPRESS OR IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, OR THAT THE USE OF THE SOFTWARE WILL NOT INFRINGE ANY PATENT,
! COPYRIGHT, TRADEMARK, OR OTHER PROPRIETARY RIGHTS, OR THAT THE SOFTWARE WILL ACCOMPLISH THE INTENDED RESULTS OR THAT THE SOFTWARE OR ITS USE WILL NOT RESULT IN INJURY OR DAMAGE.
! THE USER ASSUMES RESPONSIBILITY FOR ALL LIABILITIES, PENALTIES, FINES, CLAIMS, CAUSES OF ACTION, AND COSTS AND EXPENSES, CAUSED BY, RESULTING FROM OR ARISING OUT OF,
! IN WHOLE OR IN PART THE USE, STORAGE OR DISPOSAL OF THE SOFTWARE.
!==================================================================================================================================================================================
program MPITESTER
  use TasmanianSG
  use mpi
  implicit none

integer :: ierr, me
integer :: num_points

type(TasmanianSparseGrid) :: grid, reference_grid

call MPI_Init(ierr)

call MPI_Comm_rank(MPI_COMM_WORLD, me, ierr)

if (ierr /= MPI_SUCCESS) then
  write(*,*) "ERROR: failed to initialize MPI"
  stop 1
endif

!write(*,*) "HELLO CRUEL WORLD from me: ", me, MPI_STATUS_SIZE

call tsgAllocateGrid(grid)
call tsgAllocateGrid(reference_grid)

call tsgMakeSequenceGrid(reference_grid, 3, 1, 3, tsg_level, tsg_rleja)

if (me == 0) then
  call tsgMPIGridSend(reference_grid, 1, 11, MPI_COMM_WORLD, ierr)
endif
if (me == 1) then
  call tsgMPIGridRecv(grid, 0, 11, MPI_COMM_WORLD, MPI_STATUS_IGNORE, ierr)
  if (tsgGetNumPoints(grid) /= tsgGetNumPoints(reference_grid)) then
    write(*,*) "ERROR: failed to receive the grid"
    stop 1
  endif
  call tsgDeallocateGrid(grid) ! reset the grid
  call tsgAllocateGrid(grid)
endif

if (ierr /= MPI_SUCCESS) then
  write(*,*) "ERROR: failed at send/recv stage"
  stop 1
endif

if (me == 2) then
    call tsgMPIGridBcast(reference_grid, 2, MPI_COMM_WORLD, ierr)
    call tsgCopyGrid(grid, reference_grid)
endif
if (me /= 2) then
    call tsgMPIGridBcast(grid, 2, MPI_COMM_WORLD, ierr)
endif

if (tsgGetNumPoints(grid) /= tsgGetNumPoints(reference_grid)) then
  write(*,*) "ERROR: failed to receive the grid"
  stop 1
endif

if (ierr /= MPI_SUCCESS) then
  write(*,*) "ERROR: failed at bcast stage"
  stop 1
endif

call tsgDeallocateGrid(grid)
call tsgDeallocateGrid(reference_grid)

if (me == 0) then
  write(*,*) ""
  write(*,*) "  MPI Send/Recv/Bcast    Pass"
  write(*,*) ""
endif

call MPI_Finalize(ierr)

end program MPITESTER
