/* ====================================================================
   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.poi.xssf.usermodel;

import java.net.URI;
import java.net.URISyntaxException;

import org.apache.poi.common.usermodel.HyperlinkType;
import org.apache.poi.openxml4j.opc.PackagePart;
import org.apache.poi.openxml4j.opc.PackageRelationship;
import org.apache.poi.ss.usermodel.Hyperlink;
import org.apache.poi.ss.util.CellReference;
import org.apache.poi.util.Internal;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTHyperlink;

/**
 * XSSF Implementation of a Hyperlink.
 * Note - unlike with HSSF, many kinds of hyperlink
 * are largely stored as relations of the sheet
 */
public class XSSFHyperlink implements Hyperlink {
    final private HyperlinkType _type;
    final private PackageRelationship _externalRel;
    final private CTHyperlink _ctHyperlink; //contains a reference to the cell where the hyperlink is anchored, getRef()
    private String _location; //what the hyperlink refers to

    /**
     * Create a new XSSFHyperlink. This method is protected to be used only by
     * {@link XSSFCreationHelper#createHyperlink(int)}.
     *
     * @param type - the type of hyperlink to create, see {@link Hyperlink}
     * @deprecated POI 3.15 beta 3. Use {@link #XSSFHyperlink(HyperlinkType)} instead.
     */
    protected XSSFHyperlink(int type) {
        this(HyperlinkType.forInt(type));
    }
    
    /**
     * Create a new XSSFHyperlink. This method is protected to be used only by
     * {@link XSSFCreationHelper#createHyperlink(HyperlinkType)}.
     *
     * @param type - the type of hyperlink to create
     */
    protected XSSFHyperlink(HyperlinkType type) {
        _type = type;
        _ctHyperlink = CTHyperlink.Factory.newInstance();
        _externalRel = null;
    }

    /**
     * Create a XSSFHyperlink and initialize it from the supplied CTHyperlink bean and package relationship
     *
     * @param ctHyperlink the xml bean containing xml properties
     * @param hyperlinkRel the relationship in the underlying OPC package which stores the actual link's address
     */
    protected XSSFHyperlink(CTHyperlink ctHyperlink, PackageRelationship hyperlinkRel) {
        _ctHyperlink = ctHyperlink;
        _externalRel = hyperlinkRel;

        // Figure out the Hyperlink type and destination

        if (_externalRel == null) {
            // If it has a location, it's internal
            if (ctHyperlink.getLocation() != null) {
                _type = HyperlinkType.DOCUMENT;
                _location = ctHyperlink.getLocation();
            } else if (ctHyperlink.getId() != null) {
                throw new IllegalStateException("The hyperlink for cell "
                        + ctHyperlink.getRef() + " references relation "
                        + ctHyperlink.getId() + ", but that didn't exist!");
            } else {
                // hyperlink is internal and is not related to other parts
                _type = HyperlinkType.DOCUMENT;
            }
        } else {
            URI target = _externalRel.getTargetURI();
            _location = target.toString();
            if (ctHyperlink.getLocation() != null) {
                // URI fragment
                _location += "#" + ctHyperlink.getLocation();
            }

            // Try to figure out the type
               if (_location.startsWith("http://") || _location.startsWith("https://")
                    || _location.startsWith("ftp://")) {
                _type = HyperlinkType.URL;
            } else if (_location.startsWith("mailto:")) {
                _type = HyperlinkType.EMAIL;
            } else {
                _type = HyperlinkType.FILE;
            }
        }

     }

    /**
     * Create a new XSSFHyperlink. This method is for Internal use only.
     * XSSFHyperlinks can be created by {@link XSSFCreationHelper}.
     * See the <a href="https://poi.apache.org/spreadsheet/quick-guide.html#Hyperlinks">spreadsheet quick-guide</a>
     * for an example.
     *
     * @param other the hyperlink to copy
     */
    @Internal //FIXME: change to protected if/when SXSSFHyperlink class is created
    public XSSFHyperlink(Hyperlink other) {
        if (other instanceof XSSFHyperlink) {
            XSSFHyperlink xlink = (XSSFHyperlink) other;
            _type = xlink.getTypeEnum();
            _location = xlink._location;
            _externalRel = xlink._externalRel;
            _ctHyperlink = (CTHyperlink) xlink._ctHyperlink.copy();
        }
        else {
            _type = other.getTypeEnum();
            _location = other.getAddress();
            _externalRel = null;
            _ctHyperlink = CTHyperlink.Factory.newInstance();
            setCellReference(new CellReference(other.getFirstRow(), other.getFirstColumn()));
        }
    }
    /**
     * @return the underlying CTHyperlink object
     */
    @Internal
    public CTHyperlink getCTHyperlink() {
        return _ctHyperlink;
    }

    /**
     * Do we need to a relation too, to represent
     * this hyperlink?
     */
    public boolean needsRelationToo() {
        return (_type != HyperlinkType.DOCUMENT);
    }

    /**
     * Generates the relation if required
     */
    protected void generateRelationIfNeeded(PackagePart sheetPart) {
        if (_externalRel == null && needsRelationToo()) {
            // Generate the relation
            PackageRelationship rel =
                    sheetPart.addExternalRelationship(_location, XSSFRelation.SHEET_HYPERLINKS.getRelation());

            // Update the r:id
            _ctHyperlink.setId(rel.getId());
        }
    }

    /**
     * Return the type of this hyperlink
     *
     * @return the type of this hyperlink
     * @see HyperlinkType#forInt
     * @deprecated POI 3.15 beta 3. Use {@link #getTypeEnum()} instead.
     * getType will return a HyperlinkType enum in the future.
     */
    @Override
    public int getType() {
        return _type.getCode();
    }
    
    /**
     * Return the type of this hyperlink
     *
     * @return the type of this hyperlink
     */
    @Override
    public HyperlinkType getTypeEnum() {
        return _type;
    }

    /**
     * Get the reference of the cell this applies to,
     * es A55
     */
    public String getCellRef() {
        return _ctHyperlink.getRef();
    }

    /**
     * Hyperlink address. Depending on the hyperlink type it can be URL, e-mail, path to a file.
     * The is the hyperlink target.
     *
     * @return the address of this hyperlink
     */
    @Override
    public String getAddress() {
        return _location;
    }

    /**
     * Return text label for this hyperlink
     *
     * @return text to display
     */
    @Override
    public String getLabel() {
        return _ctHyperlink.getDisplay();
    }

    /**
     * Location within target. If target is a workbook (or this workbook) this shall refer to a
     * sheet and cell or a defined name. Can also be an HTML anchor if target is HTML file.
     *
     * @return location
     */
    public String getLocation() {
        return _ctHyperlink.getLocation();
    }

    /**
     * Sets text label for this hyperlink
     *
     * @param label text label for this hyperlink
     */
    @Override
    public void setLabel(String label) {
        _ctHyperlink.setDisplay(label);
    }

    /**
     * Location within target. If target is a workbook (or this workbook) this shall refer to a
     * sheet and cell or a defined name. Can also be an HTML anchor if target is HTML file.
     *
     * @param location - string representing a location of this hyperlink
     */
    public void setLocation(String location) {
        _ctHyperlink.setLocation(location);
    }

    /**
     * Hyperlink address. Depending on the hyperlink type it can be URL, e-mail, path to a file
     * This is the hyperlink target.
     *
     * @param address - the address of this hyperlink
     */
    @Override
    public void setAddress(String address) {
        validate(address);

       _location = address;
        //we must set location for internal hyperlinks
        if (_type == HyperlinkType.DOCUMENT) {
            setLocation(address);
        }
    }

    @SuppressWarnings("fall-through")
    private void validate(String address) {
        switch (_type) {
            // email, path to file and url must be valid URIs
            case EMAIL:
            case FILE:
            case URL:
                try {
                    new URI(address);
                } catch (URISyntaxException e) {
                    throw new IllegalArgumentException("Address of hyperlink must be a valid URI", e);
                }
                break;
            case DOCUMENT:
                // currently not evaluating anything.
                break;
            default:
                throw new IllegalStateException("Invalid Hyperlink type: " + _type);
        }
    }

    /**
     * Assigns this hyperlink to the given cell reference
     */
    @Internal
    public void setCellReference(String ref) {
        _ctHyperlink.setRef(ref);
    }
    @Internal
    public void setCellReference(CellReference ref) {
        setCellReference(ref.formatAsString());
    }

    private CellReference buildCellReference() {
        String ref = _ctHyperlink.getRef();
        if (ref == null) {
            ref = "A1";
        }
        return new CellReference(ref);
    }


    /**
     * Return the column of the first cell that contains the hyperlink
     *
     * @return the 0-based column of the first cell that contains the hyperlink
     */
    @Override
    public int getFirstColumn() {
        return buildCellReference().getCol();
    }


    /**
     * Return the column of the last cell that contains the hyperlink
     *
     * @return the 0-based column of the last cell that contains the hyperlink
     */
    @Override
    public int getLastColumn() {
        return buildCellReference().getCol();
    }

    /**
     * Return the row of the first cell that contains the hyperlink
     *
     * @return the 0-based row of the cell that contains the hyperlink
     */
    @Override
    public int getFirstRow() {
        return buildCellReference().getRow();
    }


    /**
     * Return the row of the last cell that contains the hyperlink
     *
     * @return the 0-based row of the last cell that contains the hyperlink
     */
    @Override
    public int getLastRow() {
        return buildCellReference().getRow();
    }

    /**
     * Set the column of the first cell that contains the hyperlink
     *
     * @param col the 0-based column of the first cell that contains the hyperlink
     */
    @Override
    public void setFirstColumn(int col) {
        setCellReference(new CellReference( getFirstRow(), col ));
    }

    /**
     * Set the column of the last cell that contains the hyperlink.
     * For XSSF, a Hyperlink may only reference one cell
     *
     * @param col the 0-based column of the last cell that contains the hyperlink
     */
    @Override
    public void setLastColumn(int col) {
        setFirstColumn(col);
    }

    /**
     * Set the row of the first cell that contains the hyperlink
     *
     * @param row the 0-based row of the first cell that contains the hyperlink
     */
    @Override
    public void setFirstRow(int row) {
        setCellReference(new CellReference( row, getFirstColumn() ));
    }

    /**
     * Set the row of the last cell that contains the hyperlink.
     * For XSSF, a Hyperlink may only reference one cell
     *
     * @param row the 0-based row of the last cell that contains the hyperlink
     */
    @Override
    public void setLastRow(int row) {
        setFirstRow(row);
	}

    /**
     * @return additional text to help the user understand more about the hyperlink
     */
    public String getTooltip() {
        return _ctHyperlink.getTooltip();
    }

    /**
     * @param text  additional text to help the user understand more about the hyperlink
     */
    public void setTooltip(String text) {
        _ctHyperlink.setTooltip(text);
    }
}
