# Copyright 2014 Google Inc. All Rights Reserved.
#
# 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.

"""Support for the gdal raster driver tests.

Provides tools to simplify testing a driver, which drivers are
available, and where to find test files.

Rewrite of GDALTest class:

http://trac.osgeo.org/gdal/browser/trunk/autotest/pymod/gdaltest.py#L284
"""

import contextlib
import json
from optparse import OptionParser
import os
import unittest

from osgeo import gdal
from osgeo import osr

import gflags as flags
import logging
from autotest2.gcore import gcore_util

FLAGS = flags.FLAGS

drivers = [gdal.GetDriver(i).ShortName.lower()
           for i in range(gdal.GetDriverCount())]

AAIGRID_DRIVER = 'aaigrid'
ACE2_DRIVER = 'ace2'
ADRG_DRIVER = 'adrg'
AIG_DRIVER = 'aig'
AIRSAR_DRIVER = 'airsar'
ARG_DRIVER = 'arg'
BAG_DRIVER = 'bag'
BIGGIF_DRIVER = 'biggif'
BLX_DRIVER = 'blx'
BMP_DRIVER = 'bmp'
BSB_DRIVER = 'bsb'
BT_DRIVER = 'bt'
CEOS_DRIVER = 'ceos'
COASP_DRIVER = 'coasp'
COSAR_DRIVER = 'cosar'
CPG_DRIVER = 'cpg'
CTABLE2_DRIVER = 'ctable2'
CTG_DRIVER = 'ctg'
DIMAP_DRIVER = 'dimap'
DIPEX_DRIVER = 'dipex'
DOQ1_DRIVER = 'doq1'
DOQ2_DRIVER = 'doq2'
DTED_DRIVER = 'dted'
E00GRID_DRIVER = 'e00grid'
ECRGTOC_DRIVER = 'ecrgtoc'
ECW_DRIVER = 'ecw'
EHDR_DRIVER = 'ehdr'
EIR_DRIVER = 'eir'
ELAS_DRIVER = 'elas'
ENVI_DRIVER = 'envi'
ERS_DRIVER = 'ers'
ESAT_DRIVER = 'esat'
FAST_DRIVER = 'fast'
FIT_DRIVER = 'fit'
FITS_DRIVER = 'fits'
FUJIBAS_DRIVER = 'fujibas'
GENBIN_DRIVER = 'genbin'
GFF_DRIVER = 'gff'
GIF_DRIVER = 'gif'
GMT_DRIVER = 'gmt'
GRASS_DRIVER = 'grass'
GRASSASCIIGRID_DRIVER = 'grassasciigrid'
GRIB_DRIVER = 'grib'
GS7BG_DRIVER = 'gs7bg'
GSAG_DRIVER = 'gsag'
GSBG_DRIVER = 'gsbg'
GSC_DRIVER = 'gsc'
GTIFF_DRIVER = 'gtiff'
GTX_DRIVER = 'gtx'
GXF_DRIVER = 'gxf'
HDF4_DRIVER = 'hdf4'
HDF5_DRIVER = 'hdf5'
HDF4IMAGE_DRIVER = 'hdf4image'
HDF5IMAGE_DRIVER = 'hdf5image'
HF2_DRIVER = 'hf2'
HFA_DRIVER = 'hfa'
HTTP_DRIVER = 'http'
IDA_DRIVER = 'ida'
ILWIS_DRIVER = 'ilwis'
INGR_DRIVER = 'ingr'
IRIS_DRIVER = 'iris'
ISIS2_DRIVER = 'isis2'
ISIS3_DRIVER = 'isis3'
JAXAPALSAR_DRIVER = 'jaxapalsar'
JDEM_DRIVER = 'jdem'
JP2ECW_DRIVER = 'jp2ecw'
JP2KAK_DRIVER = 'jp2kak'
JPEG2000_DRIVER = 'jpeg2000'
JP2MRSID = 'jp2mrsid'
JP2OPENJPEG = 'jp2openjpeg'
JPEG_DRIVER = 'jpeg'
JPIPKAK_DRIVER = 'jpipkak'
KMLSUPEROVERLAY_DRIVER = 'kmlsuperoverlay'
KRO_DRIVER = 'kro'
L1B_DRIVER = 'l1b'
LAN_DRIVER = 'lan'
LCP_DRIVER = 'lcp'
LEVELLER_DRIVER = 'leveller'
LOSLAS_DRIVER = 'loslas'
MAP_DRIVER = 'map'
MBTILES_DRIVER = 'mbtiles'
MEM_DRIVER = 'mem'
MFF_DRIVER = 'mff'
MFF2_DRIVER = 'mff2'
MG4LIDAR_DRIVER = 'mg4lidar'
MRSID_DRIVER = 'mrsid'
MSGN_DRIVER = 'msgn'
NDF_DRIVER = 'ndf'
NETCDF_DRIVER = 'netcdf'
NGSGEOID_DRIVER = 'ngsgeoid'
NITF_DRIVER = 'nitf'
NTV2_DRIVER = 'ntv2'
NWT_GRC_DRIVER = 'nwt_grc'
NWT_GRD_DRIVER = 'nwt_grd'
OZI_DRIVER = 'ozi'
PAUX_DRIVER = 'paux'
PCIDSK_DRIVER = 'pcidsk'
PCRASTER_DRIVER = 'pcraster'
PDF_DRIVER = 'pdf'
PDS_DRIVER = 'pds'
PNG_DRIVER = 'png'
PNM_DRIVER = 'pnm'
POSTGISRASTER_DRIVER = 'postgisraster'
R_DRIVER = 'r'
RASTERLITE_DRIVER = 'rasterlite'
RIK_DRIVER = 'rik'
RMF_DRIVER = 'rmf'
RPFTOC_DRIVER = 'rpftoc'
RS2_DRIVER = 'rs2'
RST_DRIVER = 'rst'
SAGA_DRIVER = 'saga'
SAR_CEOS_DRIVER = 'sar_ceos'
SDTS_DRIVER = 'sdts'
SGI_DRIVER = 'sgi'
SNODAS_DRIVER = 'snodas'
SRP_DRIVER = 'srp'
SRTMHGT_DRIVER = 'srtmhgt'
TERRAGEN_DRIVER = 'terragen'
TIL_DRIVER = 'til'
TSX_DRIVER = 'tsx'
USGSDEM_DRIVER = 'usgsdem'
VRT_DRIVER = 'vrt'
WCS_DRIVER = 'wcs'
WEBP_DRIVER = 'webp'
WMS_DRIVER = 'wms'
XPM_DRIVER = 'xpm'
XYZ_DRIVER = 'xyz'
ZMAP_DRIVER = 'zmap'

# A string copy of byte.tif so that tests do not need to depend on all of the
# tiff data to get a simple tiff for basic tests.
TIFF_BYTE_FILE = (
    '\x49\x49\x2a\x00\x98\x01\x00\x00\x6b\x7b\x84\x73\x84\x84\x8c\x84\x84'
    '\x84\x6b\x84\x6b\x84\x84\x6b\x7b\x73\x9c\x94\x73\x84\x6b\x7b\x94\x73'
    '\xa5\x73\x8c\x6b\x7b\x7b\x63\x84\x7b\x84\x84\x84\x63\x9c\x73\x84\x8c'
    '\x84\x7b\x73\x8c\x6b\x8c\x73\x84\x7b\x6b\x84\x84\x73\x73\x6b\x73\x6b'
    '\x94\x84\x7b\x7b\x73\x84\x84\x7b\x73\x7b\x73\x7b\x6b\x73\x94\x6b\x73'
    '\x8c\x73\x84\x84\x9c\x84\x8c\x84\x84\x73\x73\x73\x7b\x94\x7b\xa5\x7b'
    '\x84\x6b\x6b\x84\x9c\x7b\xbd\xad\xad\x94\x94\x73\x94\x7b\x6b\x84\x73'
    '\x84\x9c\x63\x7b\x73\x84\x84\xce\x6b\xc5\xad\x94\x8c\x8c\x84\x63\x84'
    '\x7b\x73\x8c\x84\x84\x63\x84\x7b\x84\xad\x7b\x73\x94\x7b\x94\x73\x94'
    '\x7b\x8c\x7b\x6b\x73\x84\x73\x6b\x73\x63\x7b\x63\xb5\x63\x6b\x7b\x73'
    '\x84\x73\x7b\x84\x73\x84\x84\x7b\x7b\x84\x63\x73\x63\x7b\x84\x73\x73'
    '\x6b\x8c\x8c\x63\x8c\x63\x73\x7b\x6b\x84\x6b\x73\x6b\x73\x7b\x84\x7b'
    '\x6b\x7b\x84\x84\x84\x84\x84\x7b\x63\x84\x7b\x6b\x94\x63\x73\x7b\x8c'
    '\xad\x7b\x6b\x7b\x7b\x7b\x6b\x7b\x7b\x7b\x6b\x8c\x7b\x7b\x73\x73\x5a'
    '\x6b\xad\x6b\x6b\x6b\x6b\x63\x84\x7b\x73\xad\x94\x63\x7b\x7b\x6b\x7b'
    '\x63\x6b\xbd\xad\x6b\x73\x73\x6b\x63\x8c\x6b\xad\x8c\x94\x84\x84\x6b'
    '\x7b\x63\x63\x73\x63\x84\x63\x8c\x73\x94\x7b\x63\x84\x7b\x94\x8c\x8c'
    '\x6b\x8c\x5a\x6b\x73\x6b\x5a\x63\x7b\x73\x73\x73\x7b\x7b\x94\x73\x94'
    '\x63\x84\xa5\x94\x9c\x7b\x6b\x6b\x6b\x73\x8c\x63\x73\x63\x63\x6b\x73'
    '\x84\x73\x5a\x7b\x73\xbd\xad\x8c\x8c\xa5\x73\x84\x5a\x63\x73\x5a\x63'
    '\x63\x6b\x63\x84\x63\x6b\x84\x84\x9c\xb5\x8c\xad\x7b\x84\x63\x73\x7b'
    '\x4a\x73\x63\x7b\x8c\x9c\x84\xa5\x8c\x8c\x63\xad\xf7\xff\xce\x84\x6b'
    '\x8c\x7b\x94\x84\xa5\xa5\x94\x8c\x84\x7b\x6b\x7b\x6b\x7b\xb5\xb5\x9c'
    '\x94\x9c\x9c\x9c\xb5\x84\x94\x73\x84\x6b\x6b\x6b\x6b\x6b\x73\x63\x6b'
    '\x0f\x00\x00\x01\x03\x00\x01\x00\x00\x00\x14\x00\x00\x00\x01\x01\x03'
    '\x00\x01\x00\x00\x00\x14\x00\x00\x00\x02\x01\x03\x00\x01\x00\x00\x00'
    '\x08\x00\x00\x00\x03\x01\x03\x00\x01\x00\x00\x00\x01\x00\x00\x00\x06'
    '\x01\x03\x00\x01\x00\x00\x00\x01\x00\x00\x00\x11\x01\x04\x00\x01\x00'
    '\x00\x00\x08\x00\x00\x00\x15\x01\x03\x00\x01\x00\x00\x00\x01\x00\x00'
    '\x00\x16\x01\x03\x00\x01\x00\x00\x00\x14\x00\x00\x00\x17\x01\x04\x00'
    '\x01\x00\x00\x00\x90\x01\x00\x00\x1c\x01\x03\x00\x01\x00\x00\x00\x01'
    '\x00\x00\x00\x53\x01\x03\x00\x01\x00\x00\x00\x01\x00\x00\x00\x0e\x83'
    '\x0c\x00\x03\x00\x00\x00\x52\x02\x00\x00\x82\x84\x0c\x00\x06\x00\x00'
    '\x00\x6a\x02\x00\x00\xaf\x87\x03\x00\x18\x00\x00\x00\x9a\x02\x00\x00'
    '\xb1\x87\x02\x00\x16\x00\x00\x00\xca\x02\x00\x00\x00\x00\x00\x00\x00'
    '\x00\x00\x00\x00\x00\x4e\x40\x00\x00\x00\x00\x00\x00\x4e\x40\x00\x00'
    '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
    '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
    '\x40\xe6\x1a\x41\x00\x00\x00\x00\xcc\x9e\x4c\x41\x00\x00\x00\x00\x00'
    '\x00\x00\x00\x01\x00\x01\x00\x00\x00\x05\x00\x00\x04\x00\x00\x01\x00'
    '\x01\x00\x01\x04\x00\x00\x01\x00\x01\x00\x02\x04\xb1\x87\x15\x00\x00'
    '\x00\x00\x0c\x00\x00\x01\x00\x57\x68\x04\x0c\x00\x00\x01\x00\x29\x23'
    '\x4e\x41\x44\x32\x37\x20\x2f\x20\x55\x54\x4d\x20\x7a\x6f\x6e\x65\x20'
    '\x31\x31\x4e\x7c\x00')


def SkipIfDriverMissing(driver_name):
  """Decorator that only runs a test if a required driver is found.

  Args:
    driver_name: Lower case short name of a driver.  e.g. 'dted'.

  Returns:
    A pass through function if the test should be run or the unittest skip
    function if the test or TestCase should not be run.
  """
  def _IdReturn(obj):
    return obj

  debug = gdal.GetConfigOption('CPL_DEBUG')
  if driver_name not in drivers:
    if debug:
      logging.info('Debug: Skipping test.  Driver not found: %s', driver_name)
    return unittest.case.skip('Skipping "%s" driver dependent test.' %
                              driver_name)
  if debug:
    logging.info('Debug: Running test.  Found driver: %s', driver_name)
  return _IdReturn


def GetTestFilePath(filename):