/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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.
 */
package org.apache.sis.storage.earthobservation;

import java.io.BufferedReader;
import java.io.IOException;
import java.util.Arrays;
import java.util.Date;
import java.util.Locale;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.io.LineNumberReader;
import java.time.LocalDate;
import java.time.OffsetDateTime;
import java.time.OffsetTime;
import java.time.DateTimeException;
import java.time.temporal.Temporal;

import org.opengis.metadata.Metadata;
import org.opengis.metadata.citation.DateType;
import org.opengis.metadata.identification.TopicCategory;
import org.opengis.metadata.spatial.DimensionNameType;
import org.opengis.metadata.content.CoverageContentType;
import org.opengis.metadata.content.TransferFunctionType;
import org.opengis.metadata.maintenance.ScopeCode;
import org.opengis.parameter.ParameterValueGroup;
import org.opengis.referencing.crs.ProjectedCRS;
import org.opengis.util.NoSuchIdentifierException;
import org.opengis.util.FactoryException;

import org.apache.sis.measure.Units;
import org.apache.sis.metadata.iso.DefaultMetadata;
import org.apache.sis.metadata.iso.DefaultIdentifier;
import org.apache.sis.metadata.iso.content.DefaultAttributeGroup;
import org.apache.sis.metadata.iso.content.DefaultBand;
import org.apache.sis.metadata.iso.content.DefaultCoverageDescription;
import org.apache.sis.metadata.sql.MetadataStoreException;
import org.apache.sis.referencing.CRS;
import org.apache.sis.referencing.CommonCRS;
import org.apache.sis.storage.DataStoreException;
import org.apache.sis.storage.DataStoreReferencingException;
import org.apache.sis.storage.event.StoreListeners;
import org.apache.sis.util.Characters;
import org.apache.sis.util.CharSequences;
import org.apache.sis.util.resources.Errors;
import org.apache.sis.util.resources.Vocabulary;
import org.apache.sis.util.iso.SimpleInternationalString;
import org.apache.sis.internal.referencing.GeodeticObjectBuilder;
import org.apache.sis.internal.referencing.ReferencingFactoryContainer;
import org.apache.sis.internal.referencing.provider.PolarStereographicB;
import org.apache.sis.internal.referencing.provider.TransverseMercator;
import org.apache.sis.internal.storage.MetadataBuilder;
import org.apache.sis.internal.util.StandardDateFormat;
import org.apache.sis.internal.util.Constants;
import org.apache.sis.internal.util.Strings;

import static org.apache.sis.internal.util.CollectionsExt.singletonOrNull;


/**
 * Parses Landsat metadata as {@linkplain DefaultMetadata ISO 19115 Metadata} object.
 * This class reads the content of a given {@link BufferedReader} from buffer position
 * until the first occurrence of the {@code END} keyword. Lines beginning with the
 * {@code #} character (ignoring spaces) are treated as comment lines and ignored.
 *
 * <p>This class will parse properties found in the Landsat metadata file,
 * except {@code GROUP} and {@code END_GROUP}. Example:
 *
 * {@preformat text
 *   DATE_ACQUIRED         = 2014-03-12
 *   SCENE_CENTER_TIME     = 03:02:01.5339408Z
 *   CORNER_UL_LAT_PRODUCT = 12.61111
 *   CORNER_UL_LON_PRODUCT = 108.33624
 *   CORNER_UR_LAT_PRODUCT = 12.62381
 *   CORNER_UR_LON_PRODUCT = 110.44017
 * }
 *
 * <p><b>NOTE FOR MAINTAINER:</b> if the work performed by this class is modified, consider updating
 * <a href="./doc-files/LandsatMetadata.html">./doc-files/LandsatMetadata.html</a> accordingly.</p>
 *
 * @author  Thi Phuong Hao Nguyen (VNSC)
 * @author  Rémi Maréchal (Geomatys)
 * @author  Martin Desruisseaux (Geomatys)
 * @version 1.0
 * @since   0.8
 * @module
 */
final class LandsatReader extends MetadataBuilder {
    /**
     * Names of Landsat bands.
     *
     * @todo Those names and the wavelength could be moved to the {@code SpatialMetadata} database,
     *       as described in <a href="https://issues.apache.org/jira/browse/SIS-338">SIS-338</a>.
     *       It would make easier to enrich the metadata with more information.
     *
     * @see #bands
     * @see #band(String, int)
     */
    private static final String[] BAND_NAMES = {
        "Coastal Aerosol",                      //   433 nm
        "Blue",                                 //   482 nm
        "Green",                                //   562 nm
        "Red",                                  //   655 nm
        "Near-Infrared",                        //   865 nm
        "Short Wavelength Infrared (SWIR) 1",   //  1610 nm
        "Short Wavelength Infrared (SWIR) 2",   //  2200 nm
        "Panchromatic",                         //   590 nm
        "Cirrus",                               //  1375 nm
        "Thermal Infrared Sensor (TIRS) 1",     // 10800 nm
        "Thermal Infrared Sensor (TIRS) 2"      // 12000 nm
    };

    /**
     * Peak response wavelength for the Landsat bands, in nanometres.
     *
     * @see #bands
     * @see #band(String, int)
     */
    private static final short[] WAVELENGTHS = {
        433, 482, 562, 655, 865, 1610, 2200, 590, 1375, 10800, 12000
    };

    /**
     * The pattern determining if the value of {@code ORIGIN} key is of the form
     * “Image courtesy of the U.S. Geological Survey”.
     */
    static final Pattern CREDIT = Pattern.compile("\\bcourtesy\\h+of\\h+(the)?\\b\\s*", Pattern.CASE_INSENSITIVE);

    /**
     * Number of spatial dimensions. This is the number of coordinate values to be stored
     * in the {@link #gridSizes} and {@link #corners} arrays for each tuple.
     */
    static final int DIM = 2;

    /**
     * The {@value} suffix added to attribute names that are followed by a band number.
     * This band suffix is itself followed by the {@code '_'} character, then the band number.
     * Example: {@code "REFLECTANCE_ADD_BAND_1"}.
     */
    private static final String BAND_SUFFIX = "_BAND";

    /**
     * A bit mask of the group in which to classify a given band.
     * There is three groups: panchromatic, reflective or thermal bands:
     *
     * <ul>
     *   <li><b>Panchromatic:</b> band  8.</li>
     *   <li><b>Reflective:</b>   bands 1, 2, 3, 4, 5, 6, 7, 9.</li>
     *   <li><b>Thermal:</b>      bands 10, 11.</li>
     * </ul>
     *
     * For a band numbered from 1 to 11 inclusive, the group is computed by
     * (constants 2 and 3 in that formula depends on the {@link #NUM_GROUPS} value):
     *
     * {@preformat java
     *   group = (BAND_GROUPS >>> 2*(band - 1)) & 3;
     * }
     *
     * The result is one of the {@link #PANCHROMATIC}, {@link #REFLECTIVE} or {@link #THERMAL} constant values
     * divided by {@value #DIM}.
     */
    static final int BAND_GROUPS = 2692437;     // Value computed by LandsatReaderTest.verifyBandGroupsMask()

    /**
     * Maximum number of band groups that a metadata may contains.
     * See {@link #BAND_GROUPS} javadoc for the list of groups.
     */
    private static final int NUM_GROUPS = 3;

    /**
     * Index of panchromatic, reflective or thermal groups in the {@link #gridSizes} array.
     * The image size is each group is given by {@value #DIM} integers: the width and the height.
     */
    static final int PANCHROMATIC = 0*DIM,
                     REFLECTIVE   = 1*DIM,
                     THERMAL      = 2*DIM;

    /**
     * Index of projected and geographic coordinates in the {@link #corners} array.
     * Each kind of coordinates are stored as 4 corners of {@value #DIM} coordinate values.
     */
    private static final int PROJECTED  = 0*DIM,
                             GEOGRAPHIC = 4*DIM;

    /**
     * The keyword for end of metadata file.
     */
    private static final String END = "END";

    /**
     * An identifier of the file being read, or {@code null} if unknown.
     * This is used mostly for formatting error messages.
     *
     * @see #getFilename()
     */
    private String filename;

    /**
     * Where to send the warnings.
     */
    private final StoreListeners listeners;

    /**
     * Group in process of being parsed, or {@code null} if none.
     */
    private String group;

    /**
     * The acquisition time, or {@code null} if not yet known. This needs to be parsed in two steps:
     * first by parsing the {@code "DATE_ACQUIRED"} attribute, then {@code "SCENE_CENTER_TIME"}.
     *
     * @see #flushSceneTime()
     */
    private Temporal sceneTime;

    /**
     * Projected and geographic coordinate values, stocked temporarily before to be saved in the extent.
     * Values are in (<var>x</var>,<var>y</var>) or (<var>lon</var>,<var>lat</var>) order.
     * The first 8 values are the projected ones. The next 8 values are the geographic ones.
     * Corner order is UL, UR, LL, LR.
     */
    private final double[] corners;

    /**
     * Image width and hight in pixels, as unsigned integers. Values are (<var>width</var>,<var>height</var>) tuples.
     * Tuples in this array are for {@link #PANCHROMATIC}, {@link #REFLECTIVE} or {@link #THERMAL} bands, in that order.
     */
    private final int[] gridSizes;

    /**
     * The bands description. Any element can be null if the corresponding band is not defined.
     * The bands can be, in this exact order:
     *
     * <ol>
     *   <li>Coastal Aerosol</li>
     *   <li>Blue</li>
     *   <li>Green</li>
     *   <li>Red</li>
     *   <li>Near-Infrared</li>
     *   <li>Short Wavelength Infrared (SWIR) 1</li>
     *   <li>Short Wavelength Infrared (SWIR) 2</li>
     *   <li>Panchromatic</li>
     *   <li>Cirrus</li>
     *   <li>Thermal Infrared Sensor (TIRS) 1</li>
     *   <li>Thermal Infrared Sensor (TIRS) 2</li>
     * </ol>
     *
     * @see #BAND_NAMES
     * @see #WAVELENGTHS
     * @see #band(String, int)
     */
    private final DefaultBand[] bands;

    /**
     * The enumeration for the {@code "DATUM"} element, to be used for creating the Coordinate Reference System.
     */
    private CommonCRS datum;

    /**
     * The Universal Transverse Mercator (UTM) zone as a number from 1 to 60 inclusive, or 0 if the zone has not
     * yet been determined. If the parser determined that the projection is Polar Stereographic, then this field
     * is set to -1.
     */
    private short utmZone;

    /**
     * The map projection parameters. This is used only for the polar stereographic case.
     */
    private ParameterValueGroup projection;

    /**
     * The referencing objects factories.
     */
    private final ReferencingFactoryContainer factories;

    /**
     * Creates a new metadata parser.
     *
     * @param  filename   an identifier of the file being read, or {@code null} if unknown.
     * @param  listeners  where to sent warnings that may occur during the parsing process.
     */
    LandsatReader(final String filename, final StoreListeners listeners) {
        this.filename  = filename;
        this.listeners = listeners;
        this.factories = new ReferencingFactoryContainer();
        this.bands     = new DefaultBand[BAND_NAMES.length];
        this.gridSizes = new int[NUM_GROUPS * DIM];
        this.corners   = new double[GEOGRAPHIC + (4*DIM)];      // GEOGRAPHIC is the last group of corners to store.
        Arrays.fill(corners, Double.NaN);
    }

    /**
     * Parses the metadata from the given characters reader.
     * The parsing stop after the first {@code "END"} keyword.
     * See class javadoc for more information on the expected format.
     *
     * @param  reader  a reader opened on the Landsat file.
     *         It is caller's responsibility to close this reader.
     * @throws IOException if an I/O error occurred while reading the given stream.
     * @throws DataStoreException if the content is not a Landsat file.
     */
    void read(final BufferedReader reader) throws IOException, DataStoreException {
        newCoverage(true);              // Starts the description of a new image.
        String line;
        while ((line = reader.readLine()) != null) {
            int end  = CharSequences.skipTrailingWhitespaces(line, 0, line.length());
            int start = CharSequences.skipLeadingWhitespaces(line, 0, end);
            if (start < end && line.charAt(start) != '#') {
                /*
                 * Separate the line into its key and value. For example in CORNER_UL_LAT_PRODUCT = 12.61111,
                 * the key will be CORNER_UL_LAT_PRODUCT and the value will be 12.61111.
                 */
                final int separator = line.indexOf('=', start);
                if (separator < 0) {
                    /*
                     * Landsat metadata ends with the END keyword, without value after that keyword.
                     * If we find it, stop reading. All remaining lines (if any) will be ignored.
                     */
                    if (end - start != END.length() || !line.regionMatches(true, start, END, 0, END.length())) {
                        throw new DataStoreException(errors().getString(Errors.Keys.NotAKeyValuePair_1, line));
                    }
                    return;
                }
                /*
                 * If the key ends with "_BAND_" followed by a number, remove the band number from the
                 * key and parse that number as an integer value. Exemple: "REFLECTANCE_ADD_BAND_1".
                 * We keep the "_BAND_" suffix in the key for avoiding ambiguity.
                 */
                String key = line.substring(start, CharSequences.skipTrailingWhitespaces(line, start, separator)).toUpperCase(Locale.US);
                int band = 0;
                for (int i=key.length(); --i >= 0;) {
                    final char c = key.charAt(i);
                    if (c < '0' || c > '9') {
                        if (c == '_') {
                            if (key.regionMatches(i - BAND_SUFFIX.length(), BAND_SUFFIX, 0, BAND_SUFFIX.length())) try {
                                band = Integer.parseInt(key.substring(++i));
                                key = key.substring(0, i);
                            } catch (NumberFormatException e) {
                                warning(key, reader, e);
                            }
                        }
                        break;
                    }
                }
                /*
                 * In a Landsat file, String values are between quotes. Example: STATION_ID = "LGN".
                 * If such quotes are found, remove them.
                 */
                start = CharSequences.skipLeadingWhitespaces(line, separator + 1, end);
                if (end - start >= 2 && line.charAt(start) == '"' && line.charAt(end - 1) == '"') {
                    start = CharSequences.skipLeadingWhitespaces(line, start + 1, --end);
                    end = CharSequences.skipTrailingWhitespaces(line, start, end);
                }
                try {
                    parseKeyValuePair(key, band, line.substring(start, end));
                } catch (IllegalArgumentException | DateTimeException e) {
                    warning(key, reader, e);
                }
            }
        }
        listeners.warning(errors().getString(Errors.Keys.UnexpectedEndOfFile_1, getFilename()));
    }

    /**
     * Parses the given string as a {@code double} value, returning a shared instance if possible.
     *
     * @param   value  the string value to parse.
     * @return  the parsed value.
     * @throws  NumberFormatException if the given value can not be parsed.
     */
    private Double parseDouble(final String value) throws NumberFormatException {
        return shared(Double.valueOf(value));
    }

    /**
     * Parses the given value and stores it at the given index in the {@link #corners} array.
     * The given index must be one of the {@link #PROJECTED} or {@link #GEOGRAPHIC} constants
     * plus the coordinate index.
     */
    private void parseCorner(final int index, final String value) throws NumberFormatException {
        corners[index] = Double.parseDouble(value);
    }

    /**
     * Parses the given value and stores it at the given index in the {@link #gridSizes} array.
     *
     * @param  index  {@link #PANCHROMATIC}, {@link #REFLECTIVE} or {@link #THERMAL},
     *                +1 if parsing the height instead than the width.
     * @param  value  the value to parse.
     */
    private void parseGridSize(final int index, final String value) throws NumberFormatException {
        gridSizes[index] = Integer.parseUnsignedInt(value);
    }

    /**
     * Invoked for every key-value pairs found in the file.
     * Leading and trailing spaces, if any, have been removed.
     *
     * @param  key    the key in upper cases.
     * @param  band   the band number, or 0 if none.
     * @param  value  the value, without quotes if those quotes existed.
     * @throws NumberFormatException if the value was expected to be a string but the parsing failed.
     * @throws DateTimeException if the value was expected to be a date but the parsing failed,
     *         or if the result of the parsing was not of the expected type.
     * @throws IllegalArgumentException if the value is out of range.
     */
    private void parseKeyValuePair(final String key, final int band, String value)
            throws IllegalArgumentException, DateTimeException, DataStoreException
    {
        switch (key) {
            case "GROUP": {
                group = value;
                break;
            }
            case "END_GROUP": {
                group = null;
                break;
            }

            ////
            //// GROUP = METADATA_FILE_INFO
            ////

            /*
             * Origin of the product.
             * Value is "Image courtesy of the U.S. Geological Survey".
             */
            case "ORIGIN": {
                final Matcher m = CREDIT.matcher(value);
                if (m.find()) {
                    newParty(MetadataBuilder.PartyType.ORGANISATION);
                    addAuthor(value.substring(m.end()));
                }
                addCredits(value);
                break;
            }
            /*
             * Product Request ID. NNNNNNNNNNNNN_UUUUU, where NNNNNNNNNNNNN = 13-digit Tracking,
             * Routing, and Metrics (TRAM) order number and UUUUU = 5-digit TRAM unit number.
             * Example: "0501403126384_00011"
             */
            case "REQUEST_ID": {
                addAcquisitionRequirement(null, value);
                break;
            }
            /*
             * The unique Landsat scene identifier.
             * Format is {@code Ls8ppprrrYYYYDDDGGGVV}.
             * Example: "LC81230522014071LGN00".
             */
            case "LANDSAT_SCENE_ID": {
                addTitleOrIdentifier(value, MetadataBuilder.Scope.ALL);
                break;
            }
            /*
             * The date when the metadata file for the L1G product set was created.
             * The date is based on Universal Time Coordinated (UTC).
             * Date format is {@code YYYY-MM-DDTHH:MM:SSZ}.
             * Example: "2014-03-12T06:06:35Z".
             */
            case "FILE_DATE": {
                addCitationDate(StandardDateFormat.toDate(OffsetDateTime.parse(value)),
                                DateType.CREATION, MetadataBuilder.Scope.ALL);
                break;
            }
            /*
             * The Ground Station that received the data. Grounds station identifiers are specified in LSDS-547.
             * Example: "LGN" = Landsat Ground Network.
             */
// TODO     case "STATION_ID":
            /*
             * The processing software version that created the product. Can be "IAS_X.Y.Z" or "LPGS_X.Y.Z"
             * where X, Y and Z are major, minor and patch version numbers.
             * Example: "LPGS_2.3.0".
             */
// TODO     case "PROCESSING_SOFTWARE_VERSION":

            ////
            //// GROUP = PRODUCT_METADATA
            ////

            /*
             * The identifier to inform the user of the product type.
             * Value can be "L1T" or "L1GT".
             */
            case "DATA_TYPE": {
                setProcessingLevelCode("Landsat", value);
                break;
            }
            /*
             * Indicates the source of the DEM used in the correction process.
             * Value can be "GLS2000", "RAMP" or "GTOPO30".
             */
            case "ELEVATION_SOURCE": {
                addSource(value, ScopeCode.MODEL, Vocabulary.formatInternational(Vocabulary.Keys.DigitalElevationModel));
                break;
            }
            /*
             * The output format of the image.
             * Value is "GEOTIFF".
             */
            case "OUTPUT_FORMAT": {
                if (Constants.GEOTIFF.equalsIgnoreCase(value)) try {
                    value = Constants.GEOTIFF;              // Because 'metadata.setFormat(…)' is case-sensitive.
                    setFormat(value);
                    break;
                } catch (MetadataStoreException e) {
                    warning(key, null, e);
                }
                addFormatName(value);
                break;
            }
            /*
             * Spacecraft from which the data were captured.
             * Example: "LANDSAT_8".
             */
            case "SPACECRAFT_ID": {
                addPlatform(null, value);
                break;
            }
            /*
             * Sensor(s) used to capture this scene.
             * Example: "OLI", "TIRS" or "OLI_TIRS".
             */
            case "SENSOR_ID": {
                addInstrument(null, value);
                break;
            }
            /*
             * The date the image was acquired.
             * Date format is {@code YYYY-MM-DD}.
             * Example: "2014-03-12".
             */
            case "DATE_ACQUIRED": {
                final LocalDate date = LocalDate.parse(value);
                if (sceneTime instanceof OffsetTime) {
                    sceneTime = date.atTime((OffsetTime) sceneTime);
                } else if (!date.equals(sceneTime)) {
                    flushSceneTime();
                    sceneTime = date;
                }
                break;
            }
            /*
             * Scene center time of the date the image was acquired.
             * Time format is {@code HH:MI:SS.SSSSSSSZ}.
             * Example: "03:02:01.5339408Z".
             */
            case "SCENE_CENTER_TIME": {
                final OffsetTime time = OffsetTime.parse(value);
                if (sceneTime instanceof LocalDate) {
                    sceneTime = ((LocalDate) sceneTime).atTime(time);
                } else {
                    sceneTime = time;
                }
                break;
            }
            /*
             * The longitude and latitude values for the upper-left (UL), upper-right (UR), lower-left (LL)
             * and lower-right (LR) corners of the product, measured at the center of the pixel.
             * Positive longitude value indicates east longitude; negative value indicates west longitude.
             * Positive latitude value indicates north latitude; negative value indicates south latitude.
             * Units are in degrees.
             */
            case "CORNER_UL_LON_PRODUCT": parseCorner(GEOGRAPHIC + 0, value); break;
            case "CORNER_UL_LAT_PRODUCT": parseCorner(GEOGRAPHIC + 1, value); break;
            case "CORNER_UR_LON_PRODUCT": parseCorner(GEOGRAPHIC + 2, value); break;
            case "CORNER_UR_LAT_PRODUCT": parseCorner(GEOGRAPHIC + 3, value); break;
            case "CORNER_LL_LON_PRODUCT": parseCorner(GEOGRAPHIC + 4, value); break;
            case "CORNER_LL_LAT_PRODUCT": parseCorner(GEOGRAPHIC + 5, value); break;
            case "CORNER_LR_LON_PRODUCT": parseCorner(GEOGRAPHIC + 6, value); break;
            case "CORNER_LR_LAT_PRODUCT": parseCorner(GEOGRAPHIC + 7, value); break;
            /*
             * The upper-left (UL), upper-right (UR), lower-left (LL) and lower-right (LR) corner map
             * projection X and Y coordinate, measured at the center of the pixel. Units are in meters.
             */
            case "CORNER_UL_PROJECTION_X_PRODUCT": parseCorner(PROJECTED + 0, value); break;
            case "CORNER_UL_PROJECTION_Y_PRODUCT": parseCorner(PROJECTED + 1, value); break;
            case "CORNER_UR_PROJECTION_X_PRODUCT": parseCorner(PROJECTED + 2, value); break;
            case "CORNER_UR_PROJECTION_Y_PRODUCT": parseCorner(PROJECTED + 3, value); break;
            case "CORNER_LL_PROJECTION_X_PRODUCT": parseCorner(PROJECTED + 4, value); break;
            case "CORNER_LL_PROJECTION_Y_PRODUCT": parseCorner(PROJECTED + 5, value); break;
            case "CORNER_LR_PROJECTION_X_PRODUCT": parseCorner(PROJECTED + 6, value); break;
            case "CORNER_LR_PROJECTION_Y_PRODUCT": parseCorner(PROJECTED + 7, value); break;
            /*
             * The number of product lines and samples for the panchromatic, reflective and thermal bands.
             * Those parameters are only present if the corresponding band is present in the product.
             */
            case "PANCHROMATIC_LINES":   parseGridSize(PANCHROMATIC + 1, value); break;
            case "PANCHROMATIC_SAMPLES": parseGridSize(PANCHROMATIC,     value); break;
            case "REFLECTIVE_LINES":     parseGridSize(REFLECTIVE + 1,   value); break;
            case "REFLECTIVE_SAMPLES":   parseGridSize(REFLECTIVE,       value); break;
            case "THERMAL_LINES":        parseGridSize(THERMAL + 1,      value); break;
            case "THERMAL_SAMPLES":      parseGridSize(THERMAL,          value); break;
            /*
             * The grid cell size in meters used in creating the image for the band, if part of the product.
             * This parameter is only included if the corresponding band is included in the product.
             */
            case "GRID_CELL_SIZE_PANCHROMATIC":
            case "GRID_CELL_SIZE_REFLECTIVE":
            case "GRID_CELL_SIZE_THERMAL": {
                addResolution(Double.parseDouble(value));
                break;
            }
            /*
             * The file name of the TIFF image that contains the pixel values for a band.
             * This parameter is only present if the band is included in the product.
             */
            case "FILE_NAME_BAND_": {
                final DefaultBand db = band(key, band);
                if (db != null) {
                    db.getNames().add(new DefaultIdentifier(value));
                }
                break;
            }
            /*
             * The file name for L1 metadata.
             * Exemple: "LC81230522014071LGN00_MTL.txt".
             */
            case "METADATA_FILE_NAME": {
                if (filename == null) {
                    filename = value;
                }
                break;
            }

            ////
            //// GROUP = IMAGE_ATTRIBUTES
            ////

            /*
             * The overall cloud coverage (percent) of the WRS-2 scene as a value between 0 and 100 inclusive.
             * -1 indicates that the score was not calculated.
             */
            case "CLOUD_COVER": {
                final double v = Double.parseDouble(value);
                if (v >= 0) setCloudCoverPercentage(v);
                break;
            }
            /*
             * The Sun azimuth angle in degrees for the image center location at the image center acquisition time.
             * Values are from -180 to 180 degrees inclusive.
             * A positive value indicates angles to the east or clockwise from the north.
             * A negative value indicates angles to the west or counterclockwise from the north.
             */
            case "SUN_AZIMUTH": {
                setIlluminationAzimuthAngle(Double.parseDouble(value));
                break;
            }
            /*
             * The Sun elevation angle in degrees for the image center location at the image center acquisition time.
             * Values are from -90 to 90 degrees inclusive.
             * A positive value indicates a daytime scene. A negative value indicates a nighttime scene.
             * Note: for reflectance calculation, the sun zenith angle is needed, which is 90 - sun elevation angle.
             */
            case "SUN_ELEVATION": {
                setIlluminationElevationAngle(Double.parseDouble(value));
                break;
            }

            ////
            //// GROUP = MIN_MAX_PIXEL_VALUE
            ////

            /*
             * Minimum achievable spectral radiance value for a band 1.
             * This parameter is only present if this band is included in the product.
             */
            case "QUANTIZE_CAL_MIN_BAND_": {
                final Double v = parseDouble(value);        // Done first in case an exception is thrown.
                final DefaultBand db = band(key, band);
                if (db != null) {
                    db.setMinValue(v);
                }
                break;
            }
            /*
             * Maximum achievable spectral radiance value for a band 1.
             * This parameter is only present if this band is included in the product.
             */
            case "QUANTIZE_CAL_MAX_BAND_": {
                final Double v = parseDouble(value);        // Done first in case an exception is thrown.
                final DefaultBand db = band(key, band);
                if (db != null) {
                    db.setMaxValue(v);
                }
                break;
            }

            ////
            //// GROUP = RADIOMETRIC_RESCALING
            ////

            /*
             * The multiplicative rescaling factor used to convert calibrated DN to Radiance units for a band.
             * Unit is W/(m² sr um)/DN.
             */
            case "RADIANCE_MULT_BAND_": {
                setTransferFunction(key, band, true, value);
                break;
            }
            /*
             * The additive rescaling factor used to convert calibrated DN to Radiance units for a band.
             * Unit is W/(m² sr um)/DN.
             */
            case "RADIANCE_ADD_BAND_": {
                setTransferFunction(key, band, false, value);
                break;
            }

            ////
            //// GROUP = PROJECTION_PARAMETERS
            ////

            /*
             * The map projection used in creating the image.
             * Universal Transverse Mercator (UTM) or Polar Stereographic (PS).
             */
            case "MAP_PROJECTION": {
                if ("UTM".equalsIgnoreCase(value)) {
                    projection = null;
                } else if ("PS".equalsIgnoreCase(value)) try {
                    projection = factories.getMathTransformFactory()
                                    .getDefaultParameters(Constants.EPSG + ':' + PolarStereographicB.IDENTIFIER);
                    utmZone = -1;
                } catch (NoSuchIdentifierException e) {
                    // Should never happen with Apache SIS implementation of MathTransformFactory.
                    throw new DataStoreReferencingException(e);
                }
                break;
            }
            /*
             * The datum used in creating the image. This is usually "WGS84".
             * We ignore the "ELLIPSOID" attribute because it is implied by the datum.
             */
            case "DATUM": {
                datum = CommonCRS.valueOf(Strings.toUpperCase(value, Characters.Filter.LETTERS_AND_DIGITS));
                break;
            }
            /*
             * The value used to indicate the zone number. This parameter is only included for the UTM projection.
             * If this parameter is defined more than once (which should be illegal), only the first occurrence is
             * retained. If the projection is polar stereographic, the parameter is ignored.
             */
            case "UTM_ZONE": {
                if (utmZone == 0) {
                    utmZone = Short.parseShort(value);
                }
                break;
            }
            /*
             * Polar Stereographic projection parameters. Most parameters do not vary, except the latitude of
             * true scale which is -71 for scenes over Antarctica and 71 for off-nadir scenes at the North Pole.
             * If the datum is WGS84, then this is equivalent to EPSG:3031 and EPSG:3995 respectively.
             */
            case "VERTICAL_LON_FROM_POLE": setProjectionParameter(key, Constants.CENTRAL_MERIDIAN,    value, false); break;
            case "TRUE_SCALE_LAT":         setProjectionParameter(key, Constants.STANDARD_PARALLEL_1, value, false); break;
            case "FALSE_EASTING":          setProjectionParameter(key, Constants.FALSE_EASTING,       value, true);  break;
            case "FALSE_NORTHING":         setProjectionParameter(key, Constants.FALSE_NORTHING,      value, true);  break;
        }
    }

    /**
     * Sets a component of the linear transfer function.
     *
     * @param  key      the key without its band number. Used only for formatting warning messages.
     * @param  band     index of the band to set.
     * @param  isScale  {@code true} for setting the scale factor, or {@code false} for setting the offset.
     * @param  value    the value to set.
     */
    private void setTransferFunction(final String key, final int band, final boolean isScale, final String value) {
        final Double v = parseDouble(value);            // Done first in case an exception is thrown.
        final DefaultBand db = band(key, band);
        if (db != null) {
            db.setTransferFunctionType(TransferFunctionType.LINEAR);
            if (isScale) {
                db.setScaleFactor(v);
            } else {
                db.setOffset(v);
            }
        }
    }

    /**
     * Returns the band at the given index, creating it if needed.
     * If the given index is out of range, then this method logs a warning and returns {@code null}.
     *
     * @param  key    the key without its band number. Used only for formatting warning messages.
     * @param  index  the band index.
     */
    private DefaultBand band(final String key, int index) {
        if (index < 1 || index > BAND_NAMES.length) {
            listeners.warning(errors().getString(Errors.Keys.UnexpectedValueInElement_2, key + index, index));
            return null;
        }
        DefaultBand band = bands[--index];
        if (band == null) {
            band = new DefaultBand();
            band.setDescription(new SimpleInternationalString(BAND_NAMES[index]));
            band.setPeakResponse((double) WAVELENGTHS[index]);
            band.setBoundUnits(Units.NANOMETRE);
            bands[index] = band;
        }
        return band;
    }

    /**
     * Sets a map projection parameter. The parameter is ignored if the projection has not been set.
     *
     * @param key       the Landsat key, for formatting error message if needed.
     * @param name      the projection parameter name.
     * @param value     the parameter value.
     * @param isLinear  {@code true} for value in metres, or {@code false} for value in degrees.
     */
    private void setProjectionParameter(final String key, final String name, final String value, final boolean isLinear) {
        if (projection != null) {
            projection.parameter(name).setValue(Double.parseDouble(value), isLinear ? Units.METRE : Units.DEGREE);
        } else {
            listeners.warning(errors().getString(Errors.Keys.UnexpectedProperty_2, filename, key));
        }
    }

    /**
     * Writes the value of {@link #sceneTime} into the metadata object as a temporal extent.
     *
     * @throws DateTimeException if {@link #sceneTime} is an instance of {@link OffsetTime}. This may
     *         happen if {@code SCENE_CENTER_TIME} attribute was found without {@code DATE_ACQUIRED}.
     */
    private void flushSceneTime() {
        final Temporal st = sceneTime;
        if (st != null) {
            sceneTime = null;                   // Clear now in case an exception it thrown below.
            final Date t = StandardDateFormat.toDate(st);
            addAcquisitionTime(t);
            try {
                addTemporalExtent(t, t);
            } catch (UnsupportedOperationException e) {
                // May happen if the temporal module (which is optional) is not on the classpath.
                warning(null, null, e);
            }
        }
    }

    /**
     * Computes the bounding box for the 8 {@link #corners} values starting at the given index.
     * Valid indices are 0 for the projected envelope or 8 for the geographic bounding box.
     * Result is stored in the 4 values starting the given {@code base} index.
     *
     * @return {@code true} of success, or {@code false} if there is no bounding box.
     */
    private boolean toBoundingBox(int base) {
        double xmin = Double.POSITIVE_INFINITY;
        double ymin = Double.POSITIVE_INFINITY;
        double xmax = Double.NEGATIVE_INFINITY;
        double ymax = Double.NEGATIVE_INFINITY;
        for (int i = base + (4*DIM); --i >= base;) {
            double v = corners[i];
            if (v < ymin) ymin = v;
            if (v > ymax) ymax = v;
            v = corners[--i];
            if (v < xmin) xmin = v;
            if (v > xmax) xmax = v;
        }
        if (xmin < xmax && ymin < ymax) {
            corners[  base] = xmin;
            corners[++base] = xmax;
            corners[++base] = ymin;
            corners[++base] = ymax;
            return true;
        }
        return false;
    }

    /**
     * Returns the metadata about the resources described in the Landsat file.
     * The {@link #read(BufferedReader)} method must be invoked at least once before.
     *
     * @throws FactoryException if an error occurred while creating the Coordinate Reference System.
     */
    final Metadata getMetadata() throws FactoryException {
        addLanguage(Locale.ENGLISH, MetadataBuilder.Scope.METADATA);
        addResourceScope(ScopeCode.COVERAGE, null);
        addTopicCategory(TopicCategory.GEOSCIENTIFIC_INFORMATION);
        try {
            flushSceneTime();
        } catch (DateTimeException e) {
            // May happen if the SCENE_CENTER_TIME attribute was found without DATE_ACQUIRED.
            warning(null, null, e);
        }
        /*
         * Create the Coordinate Reference System. We normally have only one of UTM or Polar Stereographic,
         * but this block is nevertheless capable to take both (such metadata are likely to be invalid, but
         * we can not guess which one of the two CRS is correct).
         */
        if (datum != null) {
            if (utmZone > 0) {
                addReferenceSystem(datum.universal(1, TransverseMercator.Zoner.UTM.centralMeridian(utmZone)));
            }
            if (projection != null) {
                final double sp = projection.parameter(Constants.STANDARD_PARALLEL_1).doubleValue();
                ProjectedCRS crs = (ProjectedCRS) CRS.forCode(Constants.EPSG + ":" +
                        (sp >= 0 ? Constants.EPSG_ARCTIC_POLAR_STEREOGRAPHIC         // Standard parallel = 71°N
                                 : Constants.EPSG_ANTARCTIC_POLAR_STEREOGRAPHIC));   // Standard parallel = 71°S
                if (datum != CommonCRS.WGS84 || Math.abs(sp) != 71
                        || projection.parameter(Constants.FALSE_EASTING)   .doubleValue() != 0
                        || projection.parameter(Constants.FALSE_NORTHING)  .doubleValue() != 0
                        || projection.parameter(Constants.CENTRAL_MERIDIAN).doubleValue() != 0)
                {
                    crs = new GeodeticObjectBuilder(listeners.getLocale())
                            .addName("Polar stereographic").setConversion(projection)
                            .createProjectedCRS(datum.geographic(), crs.getCoordinateSystem());
                }
                addReferenceSystem(crs);
            }
        }
        /*
         * Set information about envelope (or geographic area) and grid size.
         */
        if (toBoundingBox(GEOGRAPHIC)) {
            addExtent(corners, GEOGRAPHIC);
        }
        for (int i = 0; i < gridSizes.length; i += DIM) {
            final int width  = gridSizes[i  ];
            final int height = gridSizes[i+1];
            if ((width | height) != 0) {
                newGridRepresentation(MetadataBuilder.GridType.GEORECTIFIED);
                setAxisName(0, DimensionNameType.SAMPLE);
                setAxisName(1, DimensionNameType.LINE);
                setAxisSize(0, Integer.toUnsignedLong(width));
                setAxisSize(1, Integer.toUnsignedLong(height));
            }
        }
        /*
         * At this point we are done configuring he metadata builder. Creates the ISO 19115 metadata instance,
         * then continue adding some more specific metadata elements by ourself. For example information about
         * bands are splitted in 3 different AttributeGroups based on their grid size.
         */
        setISOStandards(true);
        final DefaultMetadata result = build(false);
        if (result != null) {
            /*
             * Set information about all non-null bands. The bands are categorized in three groups:
             * PANCHROMATIC, REFLECTIVE and THERMAL. The group in which each band belong is encoded
             * in the BAND_GROUPS bitmask.
             */
            final DefaultCoverageDescription content = (DefaultCoverageDescription) singletonOrNull(result.getContentInfo());
            if (content != null) {
                final DefaultAttributeGroup[] groups = new DefaultAttributeGroup[NUM_GROUPS];
                for (int i=0; i < bands.length; i++) {
                    final DefaultBand band = bands[i];
                    if (band != null) {
                        final int gi = (BAND_GROUPS >>> 2*i) & 3;
                        DefaultAttributeGroup group = groups[gi];
                        if (group == null) {
                            group = new DefaultAttributeGroup(CoverageContentType.PHYSICAL_MEASUREMENT, null);
                            content.getAttributeGroups().add(group);
                            groups[gi] = group;
                        }
                        group.getAttributes().add(band);
                    }
                }
            }
            result.transitionTo(DefaultMetadata.State.FINAL);
        }
        return result;
    }

    /**
     * Returns the filename to show in error messages, or a localized "unnamed" word if none.
     */
    private String getFilename() {
        return (filename != null) ? filename : Vocabulary.getResources(listeners.getLocale()).getString(Vocabulary.Keys.Unnamed);
    }

    /**
     * Prepends the group name before the given key, if a group name exists.
     * This is used only for formatting warning messages.
     */
    private String toLongName(String key) {
        if (group != null) {
            key = group + ':' + key;
        }
        return key;
    }

    /**
     * Invoked when a non-fatal exception occurred while reading metadata. This method
     * sends a record to the registered listeners if any, or logs the record otherwise.
     */
    private void warning(String key, final BufferedReader reader, final Exception e) {
        if (key != null) {
            String file = getFilename();
            if (reader instanceof LineNumberReader) {
                file = file + ":" + ((LineNumberReader) reader).getLineNumber();
            }
            key = errors().getString(Errors.Keys.CanNotReadPropertyInFile_2, toLongName(key), file);
        }
        listeners.warning(key, e);
    }

    /**
     * Returns the resources to use for formatting error messages.
     */
    private Errors errors() {
        return Errors.getResources(listeners.getLocale());
    }
}
