from osgeo import gdal, osr
import os

def convert_dat_to_tiff(dat_file, output_dir=None):
    """
    Converts a .dat raster file with an associated .hdr file to a GeoTIFF file.
    Preserves metadata, projection, and geotransformation.

    Args:
        dat_file (str): Path to the .dat file.
        output_dir (str, optional): Directory where the output TIFF file will be saved.
                                    If None, saves in the same directory as the .dat file.

    Returns:
        str: Path to the generated .tiff file.

    Raises:
        Exception: If the .hdr file is missing or the .dat file cannot be read.
    """

    # Check if .hdr file exists
    hdr_file = dat_file.replace(".dat", ".hdr")
    if not os.path.exists(hdr_file):
        raise Exception(f"Missing header file: {hdr_file}. Cannot convert {dat_file} to TIFF.")

    # Define output filename
    tiff_filename = os.path.basename(dat_file).replace(".dat", ".tiff")

    # Set output directory (use same directory as .dat if output_dir is None)
    if output_dir:
        os.makedirs(output_dir, exist_ok=True)  # Create directory if it doesn't exist
        tiff_file = os.path.join(output_dir, tiff_filename)
    else:
        tiff_file = dat_file.replace(".dat", ".tiff")

    # Open the .dat file with GDAL
    dataset = gdal.Open(dat_file, gdal.GA_ReadOnly)
    if dataset is None:
        raise Exception(f"Failed to open .dat file: {dat_file}. Ensure it has a valid .hdr file.")

    # Retrieve metadata from the original dataset
    metadata = dataset.GetMetadata()
    geotransform = dataset.GetGeoTransform()
    projection = dataset.GetProjection()

    # Create the output GeoTIFF file
    driver = gdal.GetDriverByName("GTiff")
    out_dataset = driver.CreateCopy(tiff_file, dataset, 0)

    # Set metadata, projection, and geotransform
    if metadata:
        out_dataset.SetMetadata(metadata)
    if geotransform:
        out_dataset.SetGeoTransform(geotransform)
    if projection:
        out_dataset.SetProjection(projection)

    # Close datasets
    dataset = None
    out_dataset = None

    print(f"Conversion successful: {tiff_file} (Metadata preserved)")
    return tiff_file
